@addsign/moje-agenda-shared-lib 2.0.62 → 2.0.63
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/dist/components/form/FileInput.d.ts +2 -6
- package/dist/components/form/FileInput.js +10 -12
- package/dist/components/form/FileInput.js.map +1 -1
- package/dist/components/form/FileInputMultiple.d.ts +1 -5
- package/dist/components/form/FileInputMultiple.js +8 -12
- package/dist/components/form/FileInputMultiple.js.map +1 -1
- package/dist/form-Bb28hcCd.js +404 -0
- package/dist/form-Bb28hcCd.js.map +1 -0
- package/lib/components/form/FileInput.tsx +211 -222
- package/lib/components/form/FileInputMultiple.tsx +9 -14
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@ export interface FileData {
|
|
|
8
8
|
createdByEmpId: string;
|
|
9
9
|
created: string;
|
|
10
10
|
}
|
|
11
|
-
interface FileInputProps {
|
|
11
|
+
export interface FileInputProps {
|
|
12
12
|
name: string;
|
|
13
13
|
label?: string;
|
|
14
14
|
initialFile?: FileData;
|
|
@@ -16,13 +16,9 @@ interface FileInputProps {
|
|
|
16
16
|
required?: boolean;
|
|
17
17
|
description?: string;
|
|
18
18
|
disabled?: boolean;
|
|
19
|
-
errors?: {
|
|
20
|
-
[key: string]: {
|
|
21
|
-
message: string;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
19
|
attachmentName?: string;
|
|
25
20
|
attachmentType?: string;
|
|
21
|
+
hasError?: boolean;
|
|
26
22
|
}
|
|
27
23
|
declare const FileInput: React.FC<FileInputProps>;
|
|
28
24
|
export default FileInput;
|
|
@@ -3,6 +3,7 @@ import { useState, useEffect, useCallback } from "react";
|
|
|
3
3
|
import { u as useDropzone } from "../../index-qqHvAsVd.js";
|
|
4
4
|
import "../../tailwind-l0sNRNKZ.js";
|
|
5
5
|
import { d as MdInsertDriveFile, e as MdDeleteOutline } from "../../index-CrfjcbOs.js";
|
|
6
|
+
import { cn } from "../../utils/utils.js";
|
|
6
7
|
import "../ui/input.js";
|
|
7
8
|
import "../ui/multi-select.js";
|
|
8
9
|
import "../ui/select.js";
|
|
@@ -34,11 +35,10 @@ const FileInput = ({
|
|
|
34
35
|
required,
|
|
35
36
|
description,
|
|
36
37
|
disabled,
|
|
37
|
-
errors = {},
|
|
38
38
|
attachmentName,
|
|
39
|
-
attachmentType
|
|
39
|
+
attachmentType,
|
|
40
|
+
hasError
|
|
40
41
|
}) => {
|
|
41
|
-
var _a, _b, _c, _d;
|
|
42
42
|
const [fileData, setFileData] = useState(
|
|
43
43
|
initialFile || null
|
|
44
44
|
);
|
|
@@ -129,7 +129,13 @@ const FileInput = ({
|
|
|
129
129
|
/* @__PURE__ */ jsx(
|
|
130
130
|
"div",
|
|
131
131
|
{
|
|
132
|
-
className:
|
|
132
|
+
className: cn(
|
|
133
|
+
`self-stretch px-2 py-2 rounded-lg justify-start items-center gap-2 inline-flex outline-none border`,
|
|
134
|
+
isFocused && !hasError && "outline-4 outline-indigo-200 outline-offset-0 border-indigo-300",
|
|
135
|
+
hasError && "outline-4 outline-red-200 outline-offset-0 border-none",
|
|
136
|
+
!isFocused && hasError && "border-red-200 ",
|
|
137
|
+
disabled ? "bg-gray-100" : "bg-transparent"
|
|
138
|
+
),
|
|
133
139
|
onFocus: () => setIsFocused(true),
|
|
134
140
|
onBlur: () => setIsFocused(false),
|
|
135
141
|
children: /* @__PURE__ */ jsx("div", { className: "flex relative grow shrink basis-0 min-h-5 lg:min-h-[32px] justify-start items-stretch gap-2 max-w-full ", children: !fileData ? /* @__PURE__ */ jsxs(
|
|
@@ -179,14 +185,6 @@ const FileInput = ({
|
|
|
179
185
|
id: name + ":description",
|
|
180
186
|
children: description
|
|
181
187
|
}
|
|
182
|
-
),
|
|
183
|
-
errors[name] && /* @__PURE__ */ jsx(
|
|
184
|
-
"div",
|
|
185
|
-
{
|
|
186
|
-
className: "HintText self-stretch text-red-600 text-sm font-normal leading-tight",
|
|
187
|
-
id: name + ":error",
|
|
188
|
-
children: (_d = errors[name]) == null ? void 0 : _d.message
|
|
189
|
-
}
|
|
190
188
|
)
|
|
191
189
|
] });
|
|
192
190
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileInput.js","sources":["../../../lib/components/form/FileInput.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback } from \"react\";\r\nimport { useDropzone } from \"react-dropzone\";\r\nimport { handleErrors, useFederationContext } from \"../../main\";\r\nimport { MdDeleteOutline, MdInsertDriveFile } from \"react-icons/md\";\r\nimport { AxiosError } from \"axios\";\r\n\r\nexport interface FileData {\r\n id: number;\r\n mimeType: string;\r\n size: number;\r\n filename: string;\r\n createdByEmpId: string;\r\n created: string;\r\n}\r\n\r\ninterface FileInputProps {\r\n name: string;\r\n label?: string;\r\n initialFile?: FileData;\r\n onFileChanged: (e: any) => void;\r\n required?: boolean;\r\n description?: string;\r\n disabled?: boolean;\r\n errors?: { [key: string]: { message: string } };\r\n attachmentName?: string;\r\n attachmentType?: string;\r\n}\r\n\r\nconst MAX_FILE_SIZE = 1024 * 1024; // 1MB\r\n\r\nconst FileInput: React.FC<FileInputProps> = ({\r\n initialFile,\r\n onFileChanged,\r\n label,\r\n name,\r\n required,\r\n description,\r\n disabled,\r\n errors = {},\r\n attachmentName,\r\n attachmentType,\r\n}) => {\r\n const [fileData, setFileData] = useState<FileData | null>(\r\n initialFile || null\r\n );\r\n const [isFocused, setIsFocused] = useState(false);\r\n\r\n const federationContext = useFederationContext();\r\n useEffect(() => {\r\n if (initialFile) {\r\n setFileData(initialFile);\r\n }\r\n }, [initialFile]);\r\n\r\n const onDrop = useCallback(\r\n async (acceptedFiles: File[]) => {\r\n if (acceptedFiles.length > 0) {\r\n const file = acceptedFiles[0];\r\n\r\n if (file.size > MAX_FILE_SIZE) {\r\n // Handle the case when the file size is exceeded\r\n federationContext.emitter.emit(\"message\", {\r\n title: \"Velikost souboru byla překročena\",\r\n message: `Maximální povolená velikost je ${MAX_FILE_SIZE / (1024 * 1024)} MB.`,\r\n classes: \"bg-danger \",\r\n timeout: 0,\r\n type: \"error\",\r\n });\r\n return;\r\n }\r\n\r\n const formData = new FormData();\r\n\r\n // Add the JSON data object\r\n const dataObject = {\r\n ...(attachmentName && { attachmentName }),\r\n ...(attachmentType && { attachmentType }),\r\n };\r\n\r\n formData.append(\r\n \"data\",\r\n new Blob([JSON.stringify(dataObject)], { type: \"application/json\" })\r\n );\r\n formData.append(\"file\", file);\r\n\r\n try {\r\n const response = await federationContext.apiClient.post<FileData>(\r\n \"/files/upload\",\r\n formData,\r\n {\r\n headers: {\r\n \"Content-Type\": \"multipart/form-data\",\r\n },\r\n }\r\n );\r\n setFileData(response.data);\r\n onFileChanged({\r\n target: { name, value: response.data.id.toString() },\r\n });\r\n setIsFocused(false);\r\n } catch (error) {\r\n handleErrors(error as AxiosError, federationContext.emitter);\r\n console.error(\"There was an error!\", error);\r\n }\r\n }\r\n },\r\n [\r\n federationContext.apiClient,\r\n federationContext.emitter,\r\n onFileChanged,\r\n name,\r\n attachmentName,\r\n attachmentType,\r\n ]\r\n );\r\n\r\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\r\n onDrop,\r\n disabled,\r\n multiple: false,\r\n });\r\n\r\n const handleRemove = () => {\r\n setFileData(null);\r\n onFileChanged({ target: { name, value: null } });\r\n };\r\n\r\n return (\r\n <div className=\"w-full min-h-30 flex-col justify-start items-start gap-1.5 inline-flex sharedLibrary\">\r\n <div className=\"self-stretch flex-col justify-start items-start gap-1.5 flex\">\r\n {label && (\r\n <label\r\n className=\"text-slate-700 text-sm leading-tight font-medium\"\r\n htmlFor={name}\r\n >\r\n {label} {required ? \"*\" : \"\"}\r\n </label>\r\n )}\r\n <div\r\n className={\r\n `self-stretch px-2 py-2 rounded-lg justify-start items-center gap-2 inline-flex outline-none border` +\r\n ` ${\r\n isFocused && !errors[name]?.message\r\n ? \"outline-4 outline-indigo-200 outline-offset-0 border-indigo-300\"\r\n : \"\"\r\n }` +\r\n ` ${\r\n isFocused && errors[name]?.message\r\n ? \"outline-4 outline-red-200 outline-offset-0 border-none\"\r\n : \"\"\r\n } ` +\r\n ` ${!isFocused && errors[name]?.message ? \"border-red-200\" : \"\"} ` +\r\n ` ${disabled ? \"bg-gray-100\" : \"bg-transparent\"}`\r\n }\r\n onFocus={() => setIsFocused(true)}\r\n onBlur={() => setIsFocused(false)}\r\n >\r\n <div className=\"flex relative grow shrink basis-0 min-h-5 lg:min-h-[32px] justify-start items-stretch gap-2 max-w-full \">\r\n {!fileData ? (\r\n <div\r\n {...getRootProps()}\r\n className={`w-full p-4 border-dashed border-2 rounded-lg text-center ${\r\n isDragActive\r\n ? \"border-indigo-300 bg-indigo-50\"\r\n : \"border-gray-300\"\r\n }`}\r\n >\r\n <input {...getInputProps()} id={name} />\r\n <p className=\"text-gray-500\">\r\n {isDragActive\r\n ? \"Sem přetáhněte soubor\"\r\n : \"Klikněte pro nahrání, nebo nahrajte přetažením souboru\"}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"w-full flex items-center justify-between\">\r\n <div className=\" flex\">\r\n <MdInsertDriveFile style={{ fontSize: \"2rem\" }} />\r\n <a\r\n href={`/api/files/download/${fileData.id}`}\r\n className=\"pl-2 text-left underline text-primary\"\r\n target=\"_blank\"\r\n >\r\n {fileData.filename}\r\n </a>\r\n </div>\r\n {!disabled && (\r\n <div\r\n onClick={handleRemove}\r\n className=\"text-gray-600 cursor-pointer hover:text-primary hover:bg-gray-200 rounded-full ml-4\"\r\n >\r\n <MdDeleteOutline\r\n style={{ fontSize: \"1.5rem\", margin: \"15px\" }}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n {description && (\r\n <div\r\n className=\"HintText self-stretch text-slate-600 text-sm font-normal leading-tight\"\r\n id={name + \":description\"}\r\n >\r\n {description}\r\n </div>\r\n )}\r\n {errors[name] && (\r\n <div\r\n className=\"HintText self-stretch text-red-600 text-sm font-normal leading-tight\"\r\n id={name + \":error\"}\r\n >\r\n {errors[name]?.message}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport default FileInput;\r\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FileInput.js","sources":["../../../lib/components/form/FileInput.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback } from \"react\";\nimport { useDropzone } from \"react-dropzone\";\nimport { handleErrors, useFederationContext } from \"../../main\";\nimport { MdDeleteOutline, MdInsertDriveFile } from \"react-icons/md\";\nimport { AxiosError } from \"axios\";\nimport { cn } from \"../../utils/utils\";\n\nexport interface FileData {\n id: number;\n mimeType: string;\n size: number;\n filename: string;\n createdByEmpId: string;\n created: string;\n}\n\nexport interface FileInputProps {\n name: string;\n label?: string;\n initialFile?: FileData;\n onFileChanged: (e: any) => void;\n required?: boolean;\n description?: string;\n disabled?: boolean;\n attachmentName?: string;\n attachmentType?: string;\n hasError?: boolean;\n}\n\nconst MAX_FILE_SIZE = 1024 * 1024; // 1MB\n\nconst FileInput: React.FC<FileInputProps> = ({\n initialFile,\n onFileChanged,\n label,\n name,\n required,\n description,\n disabled,\n attachmentName,\n attachmentType,\n hasError,\n}) => {\n const [fileData, setFileData] = useState<FileData | null>(\n initialFile || null\n );\n const [isFocused, setIsFocused] = useState(false);\n\n const federationContext = useFederationContext();\n useEffect(() => {\n if (initialFile) {\n setFileData(initialFile);\n }\n }, [initialFile]);\n\n const onDrop = useCallback(\n async (acceptedFiles: File[]) => {\n if (acceptedFiles.length > 0) {\n const file = acceptedFiles[0];\n\n if (file.size > MAX_FILE_SIZE) {\n // Handle the case when the file size is exceeded\n federationContext.emitter.emit(\"message\", {\n title: \"Velikost souboru byla překročena\",\n message: `Maximální povolená velikost je ${MAX_FILE_SIZE / (1024 * 1024)} MB.`,\n classes: \"bg-danger \",\n timeout: 0,\n type: \"error\",\n });\n return;\n }\n\n const formData = new FormData();\n\n // Add the JSON data object\n const dataObject = {\n ...(attachmentName && { attachmentName }),\n ...(attachmentType && { attachmentType }),\n };\n\n formData.append(\n \"data\",\n new Blob([JSON.stringify(dataObject)], { type: \"application/json\" })\n );\n formData.append(\"file\", file);\n\n try {\n const response = await federationContext.apiClient.post<FileData>(\n \"/files/upload\",\n formData,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n setFileData(response.data);\n onFileChanged({\n target: { name, value: response.data.id.toString() },\n });\n setIsFocused(false);\n } catch (error) {\n handleErrors(error as AxiosError, federationContext.emitter);\n console.error(\"There was an error!\", error);\n }\n }\n },\n [\n federationContext.apiClient,\n federationContext.emitter,\n onFileChanged,\n name,\n attachmentName,\n attachmentType,\n ]\n );\n\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\n onDrop,\n disabled,\n multiple: false,\n });\n\n const handleRemove = () => {\n setFileData(null);\n onFileChanged({ target: { name, value: null } });\n };\n\n return (\n <div className=\"w-full min-h-30 flex-col justify-start items-start gap-1.5 inline-flex sharedLibrary\">\n <div className=\"self-stretch flex-col justify-start items-start gap-1.5 flex\">\n {label && (\n <label\n className=\"text-slate-700 text-sm leading-tight font-medium\"\n htmlFor={name}\n >\n {label} {required ? \"*\" : \"\"}\n </label>\n )}\n <div\n className={cn(\n `self-stretch px-2 py-2 rounded-lg justify-start items-center gap-2 inline-flex outline-none border`,\n isFocused &&\n !hasError &&\n \"outline-4 outline-indigo-200 outline-offset-0 border-indigo-300\",\n\n hasError &&\n \"outline-4 outline-red-200 outline-offset-0 border-none\",\n !isFocused && hasError && \"border-red-200 \",\n disabled ? \"bg-gray-100\" : \"bg-transparent\"\n )}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n >\n <div className=\"flex relative grow shrink basis-0 min-h-5 lg:min-h-[32px] justify-start items-stretch gap-2 max-w-full \">\n {!fileData ? (\n <div\n {...getRootProps()}\n className={`w-full p-4 border-dashed border-2 rounded-lg text-center ${\n isDragActive\n ? \"border-indigo-300 bg-indigo-50\"\n : \"border-gray-300\"\n }`}\n >\n <input {...getInputProps()} id={name} />\n <p className=\"text-gray-500\">\n {isDragActive\n ? \"Sem přetáhněte soubor\"\n : \"Klikněte pro nahrání, nebo nahrajte přetažením souboru\"}\n </p>\n </div>\n ) : (\n <div className=\"w-full flex items-center justify-between\">\n <div className=\" flex\">\n <MdInsertDriveFile style={{ fontSize: \"2rem\" }} />\n <a\n href={`/api/files/download/${fileData.id}`}\n className=\"pl-2 text-left underline text-primary\"\n target=\"_blank\"\n >\n {fileData.filename}\n </a>\n </div>\n {!disabled && (\n <div\n onClick={handleRemove}\n className=\"text-gray-600 cursor-pointer hover:text-primary hover:bg-gray-200 rounded-full ml-4\"\n >\n <MdDeleteOutline\n style={{ fontSize: \"1.5rem\", margin: \"15px\" }}\n />\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n {description && (\n <div\n className=\"HintText self-stretch text-slate-600 text-sm font-normal leading-tight\"\n id={name + \":description\"}\n >\n {description}\n </div>\n )}\n </div>\n );\n};\n\nexport default FileInput;\n"],"names":[],"mappings":"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"}
|
|
@@ -9,14 +9,10 @@ interface FileInputMultipleProps {
|
|
|
9
9
|
required?: boolean;
|
|
10
10
|
description?: string;
|
|
11
11
|
disabled?: boolean;
|
|
12
|
-
errors?: {
|
|
13
|
-
[key: string]: {
|
|
14
|
-
message: string;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
12
|
initialFilesReadOnly?: boolean;
|
|
18
13
|
attachmentName?: string;
|
|
19
14
|
attachmentType?: string;
|
|
15
|
+
hasError?: boolean;
|
|
20
16
|
}
|
|
21
17
|
declare const FileInputMultiple: React.FC<FileInputMultipleProps>;
|
|
22
18
|
export default FileInputMultiple;
|
|
@@ -3,6 +3,7 @@ import { useState, useEffect, useCallback } from "react";
|
|
|
3
3
|
import { u as useDropzone } from "../../index-qqHvAsVd.js";
|
|
4
4
|
import { d as MdInsertDriveFile, e as MdDeleteOutline } from "../../index-CrfjcbOs.js";
|
|
5
5
|
import "../../tailwind-l0sNRNKZ.js";
|
|
6
|
+
import { cn } from "../../utils/utils.js";
|
|
6
7
|
import "../ui/input.js";
|
|
7
8
|
import "../ui/multi-select.js";
|
|
8
9
|
import "../ui/select.js";
|
|
@@ -34,12 +35,11 @@ const FileInputMultiple = ({
|
|
|
34
35
|
required,
|
|
35
36
|
description,
|
|
36
37
|
disabled,
|
|
37
|
-
errors = {},
|
|
38
38
|
initialFilesReadOnly = true,
|
|
39
39
|
attachmentName,
|
|
40
|
-
attachmentType
|
|
40
|
+
attachmentType,
|
|
41
|
+
hasError
|
|
41
42
|
}) => {
|
|
42
|
-
var _a, _b;
|
|
43
43
|
const [fileDataList, setFileDataList] = useState(
|
|
44
44
|
initialFiles ? [...initialFiles].map((file) => ({
|
|
45
45
|
...file,
|
|
@@ -154,7 +154,11 @@ const FileInputMultiple = ({
|
|
|
154
154
|
/* @__PURE__ */ jsxs(
|
|
155
155
|
"div",
|
|
156
156
|
{
|
|
157
|
-
className:
|
|
157
|
+
className: cn(
|
|
158
|
+
`self-stretch px-3 py-2 rounded-lg justify-start items-center gap-2 outline-none border bg-transparent `,
|
|
159
|
+
hasError && "outline-4 outline-red-200 outline-offset-0 border-none ",
|
|
160
|
+
disabled ? "bg-gray-100" : "bg-transparent"
|
|
161
|
+
),
|
|
158
162
|
children: [
|
|
159
163
|
!disabled && /* @__PURE__ */ jsxs(
|
|
160
164
|
"div",
|
|
@@ -214,14 +218,6 @@ const FileInputMultiple = ({
|
|
|
214
218
|
id: name + ":description",
|
|
215
219
|
children: description
|
|
216
220
|
}
|
|
217
|
-
),
|
|
218
|
-
errors[name] && /* @__PURE__ */ jsx(
|
|
219
|
-
"div",
|
|
220
|
-
{
|
|
221
|
-
className: "HintText self-stretch text-red-600 text-sm font-normal leading-tight",
|
|
222
|
-
id: name + ":error",
|
|
223
|
-
children: (_b = errors[name]) == null ? void 0 : _b.message
|
|
224
|
-
}
|
|
225
221
|
)
|
|
226
222
|
] });
|
|
227
223
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileInputMultiple.js","sources":["../../../lib/components/form/FileInputMultiple.tsx"],"sourcesContent":["import React, { useState, useCallback, useEffect } from \"react\";\r\nimport { useDropzone } from \"react-dropzone\";\r\nimport { MdDeleteOutline, MdInsertDriveFile } from \"react-icons/md\";\r\nimport { IAttachment } from \"../../types\";\r\nimport { handleErrors, useFederationContext } from \"../../main\";\r\nimport { AxiosError } from \"axios\";\r\n\r\ninterface FileInputMultipleProps {\r\n name: string;\r\n label?: string;\r\n initialFiles?: IAttachment[];\r\n onFilesChanged: (e: any) => void;\r\n required?: boolean;\r\n description?: string;\r\n disabled?: boolean;\r\n errors?: { [key: string]: { message: string } };\r\n initialFilesReadOnly?: boolean;\r\n attachmentName?: string;\r\n attachmentType?: string;\r\n}\r\n\r\ninterface IAttachmentReadOnly extends IAttachment {\r\n readonly?: boolean;\r\n}\r\n\r\nconst MAX_FILE_SIZE = 1024 * 1024; // 1MB\r\n\r\nconst FileInputMultiple: React.FC<FileInputMultipleProps> = ({\r\n initialFiles,\r\n onFilesChanged,\r\n label,\r\n name,\r\n required,\r\n description,\r\n disabled,\r\n errors = {},\r\n initialFilesReadOnly = true,\r\n attachmentName,\r\n attachmentType,\r\n}) => {\r\n const [fileDataList, setFileDataList] = useState<IAttachmentReadOnly[]>(\r\n initialFiles\r\n ? [...initialFiles].map((file) => ({\r\n ...file,\r\n readonly: initialFilesReadOnly,\r\n }))\r\n : []\r\n );\r\n const federationContext = useFederationContext();\r\n\r\n useEffect(() => {\r\n console.log(\r\n \"%clibcomponents\\formFileInputMultiple.tsx:40 initialFiles\",\r\n \"color: #007acc;\",\r\n initialFiles\r\n );\r\n if (!initialFiles || initialFiles.length === 0) return;\r\n setFileDataList(\r\n [...initialFiles].map((file) => ({\r\n ...file,\r\n readonly: initialFilesReadOnly,\r\n }))\r\n );\r\n }, [initialFiles, initialFilesReadOnly]);\r\n\r\n const onDrop = useCallback(\r\n async (acceptedFiles: File[]) => {\r\n const uploadedFiles = await Promise.all(\r\n acceptedFiles.map(async (file) => {\r\n if (file.size > MAX_FILE_SIZE) {\r\n // Handle the case when the file size is exceeded\r\n\r\n federationContext.emitter.emit(\"message\", {\r\n title: \"Velikost souboru byla překročena\",\r\n message: `Maximální povolená velikost je ${MAX_FILE_SIZE / (1024 * 1024)} MB.`,\r\n classes: \"bg-danger \",\r\n timeout: 0,\r\n type: \"error\",\r\n });\r\n\r\n return null;\r\n }\r\n\r\n const formData = new FormData();\r\n\r\n // Add the JSON data object\r\n const dataObject = {\r\n ...(attachmentName && { attachmentName }),\r\n ...(attachmentType && { attachmentType }),\r\n };\r\n\r\n formData.append(\r\n \"data\",\r\n new Blob([JSON.stringify(dataObject)], { type: \"application/json\" })\r\n );\r\n formData.append(\"file\", file);\r\n\r\n try {\r\n const response =\r\n await federationContext.apiClient.post<IAttachment>(\r\n \"/files/upload\",\r\n formData,\r\n {\r\n headers: {\r\n \"Content-Type\": \"multipart/form-data\",\r\n },\r\n }\r\n );\r\n return response.data;\r\n } catch (error) {\r\n handleErrors(error as AxiosError, federationContext.emitter);\r\n console.error(\"There was an error!\", error);\r\n return null;\r\n }\r\n })\r\n );\r\n\r\n const validFiles = uploadedFiles.filter(\r\n (file) => file !== null\r\n ) as IAttachment[];\r\n const updatedFileDataList = [...fileDataList, ...validFiles];\r\n setFileDataList(updatedFileDataList);\r\n onFilesChanged({\r\n target: {\r\n name,\r\n value: updatedFileDataList.map((file) => file.id.toString()),\r\n },\r\n });\r\n },\r\n [federationContext, fileDataList, onFilesChanged, name, attachmentName]\r\n );\r\n\r\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\r\n onDrop,\r\n disabled,\r\n });\r\n\r\n const handleRemove = (fileId: number) => {\r\n const updatedFileDataList = fileDataList.filter(\r\n (file) => file.id !== fileId\r\n );\r\n setFileDataList(updatedFileDataList);\r\n onFilesChanged({\r\n target: {\r\n name,\r\n value: updatedFileDataList.map((file) => file.id.toString()),\r\n },\r\n });\r\n };\r\n if (disabled === true && fileDataList.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className=\"w-full min-h-30 flex-col justify-start items-start gap-1.5 inline-flex sharedLibrary\">\r\n <div className=\"self-stretch flex-col justify-start items-start gap-1.5 flex\">\r\n {label && (\r\n <label\r\n className=\"text-slate-700 text-sm leading-tight font-medium\"\r\n htmlFor={name}\r\n >\r\n {label} {required ? \"*\" : \"\"}\r\n </label>\r\n )}\r\n <div\r\n className={\r\n `self-stretch px-3 py-2 rounded-lg justify-start items-center gap-2 outline-none border bg-transparent ` +\r\n ` ${errors[name]?.message ? \"border-red-200\" : \"border-gray-300\"} `\r\n }\r\n >\r\n {!disabled && (\r\n <div\r\n {...getRootProps()}\r\n className={`w-full p-4 border-dashed cursor-pointer \r\n border-2 rounded-lg text-center hover:bg-gray-100\r\n ${isDragActive ? \"border-indigo-300 bg-indigo-50\" : \"border-gray-300\"}`}\r\n >\r\n <input {...getInputProps()} id={name} />\r\n <p className=\"text-gray-500\">\r\n {isDragActive\r\n ? \"Sem přetáhněte soubory\"\r\n : \"Klikněte pro nahrání, nebo nahrajte přetažením souborů\"}\r\n </p>\r\n </div>\r\n )}\r\n <div className=\"w-full\">\r\n {fileDataList.map((file) => (\r\n <div\r\n key={file.id}\r\n className=\"w-full flex items-center justify-between py-2 border-b \"\r\n >\r\n <div className=\"flex items-center content-center\">\r\n <MdInsertDriveFile style={{ fontSize: \"2rem\" }} />\r\n <a\r\n href={`/api/files/download/${file.id}`}\r\n className=\"pl-2 text-left underline text-primary\"\r\n target=\"_blank\"\r\n >\r\n {file.filename}\r\n </a>\r\n </div>\r\n {!disabled && file.readonly !== true && (\r\n <div\r\n onClick={() => handleRemove(file.id)}\r\n className=\"text-gray-600 cursor-pointer hover:text-primary hover:bg-gray-200 rounded-full ml-4\"\r\n >\r\n <MdDeleteOutline\r\n style={{ fontSize: \"1.5rem\", margin: \"10px\" }}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n {description && (\r\n <div\r\n className=\"HintText self-stretch text-slate-600 text-sm font-normal leading-tight\"\r\n id={name + \":description\"}\r\n >\r\n {description}\r\n </div>\r\n )}\r\n {errors[name] && (\r\n <div\r\n className=\"HintText self-stretch text-red-600 text-sm font-normal leading-tight\"\r\n id={name + \":error\"}\r\n >\r\n {errors[name]?.message}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport default FileInputMultiple;\r\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAM,gBAAgB,OAAO;AAE7B,MAAM,oBAAsD,CAAC;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS,CAAC;AAAA,EACV,uBAAuB;AAAA,EACvB;AAAA,EACA;AACF,MAAM;;AACE,QAAA,CAAC,cAAc,eAAe,IAAI;AAAA,IACtC,eACI,CAAC,GAAG,YAAY,EAAE,IAAI,CAAC,UAAU;AAAA,MAC/B,GAAG;AAAA,MACH,UAAU;AAAA,IACZ,EAAE,IACF,CAAC;AAAA,EAAA;AAEP,QAAM,oBAAoB;AAE1B,YAAU,MAAM;AACN,YAAA;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEE,QAAA,CAAC,gBAAgB,aAAa,WAAW;AAAG;AAChD;AAAA,MACE,CAAC,GAAG,YAAY,EAAE,IAAI,CAAC,UAAU;AAAA,QAC/B,GAAG;AAAA,QACH,UAAU;AAAA,MAAA,EACV;AAAA,IAAA;AAAA,EACJ,GACC,CAAC,cAAc,oBAAoB,CAAC;AAEvC,QAAM,SAAS;AAAA,IACb,OAAO,kBAA0B;AACzB,YAAA,gBAAgB,MAAM,QAAQ;AAAA,QAClC,cAAc,IAAI,OAAO,SAAS;AAC5B,cAAA,KAAK,OAAO,eAAe;AAGX,8BAAA,QAAQ,KAAK,WAAW;AAAA,cACxC,OAAO;AAAA,cACP,SAAS,kCAAkC,iBAAiB,OAAO,KAAK;AAAA,cACxE,SAAS;AAAA,cACT,SAAS;AAAA,cACT,MAAM;AAAA,YAAA,CACP;AAEM,mBAAA;AAAA,UACT;AAEM,gBAAA,WAAW,IAAI;AAGrB,gBAAM,aAAa;AAAA,YACjB,GAAI,kBAAkB,EAAE,eAAe;AAAA,YACvC,GAAI,kBAAkB,EAAE,eAAe;AAAA,UAAA;AAGhC,mBAAA;AAAA,YACP;AAAA,YACA,IAAI,KAAK,CAAC,KAAK,UAAU,UAAU,CAAC,GAAG,EAAE,MAAM,oBAAoB;AAAA,UAAA;AAE5D,mBAAA,OAAO,QAAQ,IAAI;AAExB,cAAA;AACI,kBAAA,WACJ,MAAM,kBAAkB,UAAU;AAAA,cAChC;AAAA,cACA;AAAA,cACA;AAAA,gBACE,SAAS;AAAA,kBACP,gBAAgB;AAAA,gBAClB;AAAA,cACF;AAAA,YAAA;AAEJ,mBAAO,SAAS;AAAA,mBACT,OAAO;AACD,yBAAA,OAAqB,kBAAkB,OAAO;AACnD,oBAAA,MAAM,uBAAuB,KAAK;AACnC,mBAAA;AAAA,UACT;AAAA,QAAA,CACD;AAAA,MAAA;AAGH,YAAM,aAAa,cAAc;AAAA,QAC/B,CAAC,SAAS,SAAS;AAAA,MAAA;AAErB,YAAM,sBAAsB,CAAC,GAAG,cAAc,GAAG,UAAU;AAC3D,sBAAgB,mBAAmB;AACpB,qBAAA;AAAA,QACb,QAAQ;AAAA,UACN;AAAA,UACA,OAAO,oBAAoB,IAAI,CAAC,SAAS,KAAK,GAAG,UAAU;AAAA,QAC7D;AAAA,MAAA,CACD;AAAA,IACH;AAAA,IACA,CAAC,mBAAmB,cAAc,gBAAgB,MAAM,cAAc;AAAA,EAAA;AAGxE,QAAM,EAAE,cAAc,eAAe,aAAA,IAAiB,YAAY;AAAA,IAChE;AAAA,IACA;AAAA,EAAA,CACD;AAEK,QAAA,eAAe,CAAC,WAAmB;AACvC,UAAM,sBAAsB,aAAa;AAAA,MACvC,CAAC,SAAS,KAAK,OAAO;AAAA,IAAA;AAExB,oBAAgB,mBAAmB;AACpB,mBAAA;AAAA,MACb,QAAQ;AAAA,QACN;AAAA,QACA,OAAO,oBAAoB,IAAI,CAAC,SAAS,KAAK,GAAG,UAAU;AAAA,MAC7D;AAAA,IAAA,CACD;AAAA,EAAA;AAEH,MAAI,aAAa,QAAQ,aAAa,WAAW,GAAG;AAC3C,WAAA;AAAA,EACT;AAGE,SAAA,qBAAC,OAAI,EAAA,WAAU,wFACb,UAAA;AAAA,IAAC,qBAAA,OAAA,EAAI,WAAU,gEACZ,UAAA;AAAA,MACC,SAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,SAAS;AAAA,UAER,UAAA;AAAA,YAAA;AAAA,YAAM;AAAA,YAAE,WAAW,MAAM;AAAA,UAAA;AAAA,QAAA;AAAA,MAC5B;AAAA,MAEF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WACE,6GACI,YAAO,IAAI,MAAX,mBAAc,WAAU,mBAAmB,iBAAiB;AAAA,UAGjE,UAAA;AAAA,YAAA,CAAC,YACA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACE,GAAG,aAAa;AAAA,gBACjB,WAAW;AAAA;AAAA,kBAEP,eAAe,mCAAmC,iBAAiB;AAAA,gBAEvE,UAAA;AAAA,kBAAA,oBAAC,SAAO,EAAA,GAAG,cAAc,GAAG,IAAI,MAAM;AAAA,sCACrC,KAAE,EAAA,WAAU,iBACV,UAAA,eACG,2BACA,0DACN;AAAA,gBAAA;AAAA,cAAA;AAAA,YACF;AAAA,gCAED,OAAI,EAAA,WAAU,UACZ,UAAa,aAAA,IAAI,CAAC,SACjB;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBAEV,UAAA;AAAA,kBAAC,qBAAA,OAAA,EAAI,WAAU,oCACb,UAAA;AAAA,oBAAA,oBAAC,mBAAkB,EAAA,OAAO,EAAE,UAAU,UAAU;AAAA,oBAChD;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,MAAM,uBAAuB,KAAK,EAAE;AAAA,wBACpC,WAAU;AAAA,wBACV,QAAO;AAAA,wBAEN,UAAK,KAAA;AAAA,sBAAA;AAAA,oBACR;AAAA,kBAAA,GACF;AAAA,kBACC,CAAC,YAAY,KAAK,aAAa,QAC9B;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,SAAS,MAAM,aAAa,KAAK,EAAE;AAAA,sBACnC,WAAU;AAAA,sBAEV,UAAA;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACC,OAAO,EAAE,UAAU,UAAU,QAAQ,OAAO;AAAA,wBAAA;AAAA,sBAC9C;AAAA,oBAAA;AAAA,kBACF;AAAA,gBAAA;AAAA,cAAA;AAAA,cArBG,KAAK;AAAA,YAwBb,CAAA,GACH;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA,GACF;AAAA,IACC,eACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,IAAI,OAAO;AAAA,QAEV,UAAA;AAAA,MAAA;AAAA,IACH;AAAA,IAED,OAAO,IAAI,KACV;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,IAAI,OAAO;AAAA,QAEV,WAAA,YAAO,IAAI,MAAX,mBAAc;AAAA,MAAA;AAAA,IACjB;AAAA,EAEJ,EAAA,CAAA;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"FileInputMultiple.js","sources":["../../../lib/components/form/FileInputMultiple.tsx"],"sourcesContent":["import React, { useState, useCallback, useEffect } from \"react\";\r\nimport { useDropzone } from \"react-dropzone\";\r\nimport { MdDeleteOutline, MdInsertDriveFile } from \"react-icons/md\";\r\nimport { IAttachment } from \"../../types\";\r\nimport { handleErrors, useFederationContext } from \"../../main\";\r\nimport { AxiosError } from \"axios\";\r\nimport { cn } from \"../../utils/utils\";\r\n\r\ninterface FileInputMultipleProps {\r\n name: string;\r\n label?: string;\r\n initialFiles?: IAttachment[];\r\n onFilesChanged: (e: any) => void;\r\n required?: boolean;\r\n description?: string;\r\n disabled?: boolean;\r\n initialFilesReadOnly?: boolean;\r\n attachmentName?: string;\r\n attachmentType?: string;\r\n hasError?: boolean;\r\n}\r\n\r\ninterface IAttachmentReadOnly extends IAttachment {\r\n readonly?: boolean;\r\n}\r\n\r\nconst MAX_FILE_SIZE = 1024 * 1024; // 1MB\r\n\r\nconst FileInputMultiple: React.FC<FileInputMultipleProps> = ({\r\n initialFiles,\r\n onFilesChanged,\r\n label,\r\n name,\r\n required,\r\n description,\r\n disabled,\r\n initialFilesReadOnly = true,\r\n attachmentName,\r\n attachmentType,\r\n hasError,\r\n}) => {\r\n const [fileDataList, setFileDataList] = useState<IAttachmentReadOnly[]>(\r\n initialFiles\r\n ? [...initialFiles].map((file) => ({\r\n ...file,\r\n readonly: initialFilesReadOnly,\r\n }))\r\n : []\r\n );\r\n const federationContext = useFederationContext();\r\n\r\n useEffect(() => {\r\n console.log(\r\n \"%clibcomponents\\formFileInputMultiple.tsx:40 initialFiles\",\r\n \"color: #007acc;\",\r\n initialFiles\r\n );\r\n if (!initialFiles || initialFiles.length === 0) return;\r\n setFileDataList(\r\n [...initialFiles].map((file) => ({\r\n ...file,\r\n readonly: initialFilesReadOnly,\r\n }))\r\n );\r\n }, [initialFiles, initialFilesReadOnly]);\r\n\r\n const onDrop = useCallback(\r\n async (acceptedFiles: File[]) => {\r\n const uploadedFiles = await Promise.all(\r\n acceptedFiles.map(async (file) => {\r\n if (file.size > MAX_FILE_SIZE) {\r\n // Handle the case when the file size is exceeded\r\n\r\n federationContext.emitter.emit(\"message\", {\r\n title: \"Velikost souboru byla překročena\",\r\n message: `Maximální povolená velikost je ${MAX_FILE_SIZE / (1024 * 1024)} MB.`,\r\n classes: \"bg-danger \",\r\n timeout: 0,\r\n type: \"error\",\r\n });\r\n\r\n return null;\r\n }\r\n\r\n const formData = new FormData();\r\n\r\n // Add the JSON data object\r\n const dataObject = {\r\n ...(attachmentName && { attachmentName }),\r\n ...(attachmentType && { attachmentType }),\r\n };\r\n\r\n formData.append(\r\n \"data\",\r\n new Blob([JSON.stringify(dataObject)], { type: \"application/json\" })\r\n );\r\n formData.append(\"file\", file);\r\n\r\n try {\r\n const response =\r\n await federationContext.apiClient.post<IAttachment>(\r\n \"/files/upload\",\r\n formData,\r\n {\r\n headers: {\r\n \"Content-Type\": \"multipart/form-data\",\r\n },\r\n }\r\n );\r\n return response.data;\r\n } catch (error) {\r\n handleErrors(error as AxiosError, federationContext.emitter);\r\n console.error(\"There was an error!\", error);\r\n return null;\r\n }\r\n })\r\n );\r\n\r\n const validFiles = uploadedFiles.filter(\r\n (file) => file !== null\r\n ) as IAttachment[];\r\n const updatedFileDataList = [...fileDataList, ...validFiles];\r\n setFileDataList(updatedFileDataList);\r\n onFilesChanged({\r\n target: {\r\n name,\r\n value: updatedFileDataList.map((file) => file.id.toString()),\r\n },\r\n });\r\n },\r\n [federationContext, fileDataList, onFilesChanged, name, attachmentName]\r\n );\r\n\r\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\r\n onDrop,\r\n disabled,\r\n });\r\n\r\n const handleRemove = (fileId: number) => {\r\n const updatedFileDataList = fileDataList.filter(\r\n (file) => file.id !== fileId\r\n );\r\n setFileDataList(updatedFileDataList);\r\n onFilesChanged({\r\n target: {\r\n name,\r\n value: updatedFileDataList.map((file) => file.id.toString()),\r\n },\r\n });\r\n };\r\n if (disabled === true && fileDataList.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className=\"w-full min-h-30 flex-col justify-start items-start gap-1.5 inline-flex sharedLibrary\">\r\n <div className=\"self-stretch flex-col justify-start items-start gap-1.5 flex\">\r\n {label && (\r\n <label\r\n className=\"text-slate-700 text-sm leading-tight font-medium\"\r\n htmlFor={name}\r\n >\r\n {label} {required ? \"*\" : \"\"}\r\n </label>\r\n )}\r\n <div\r\n className={cn(\r\n `self-stretch px-3 py-2 rounded-lg justify-start items-center gap-2 outline-none border bg-transparent `,\r\n hasError &&\r\n \"outline-4 outline-red-200 outline-offset-0 border-none \",\r\n disabled ? \"bg-gray-100\" : \"bg-transparent\"\r\n )}\r\n >\r\n {!disabled && (\r\n <div\r\n {...getRootProps()}\r\n className={`w-full p-4 border-dashed cursor-pointer \r\n border-2 rounded-lg text-center hover:bg-gray-100\r\n ${isDragActive ? \"border-indigo-300 bg-indigo-50\" : \"border-gray-300\"}`}\r\n >\r\n <input {...getInputProps()} id={name} />\r\n <p className=\"text-gray-500\">\r\n {isDragActive\r\n ? \"Sem přetáhněte soubory\"\r\n : \"Klikněte pro nahrání, nebo nahrajte přetažením souborů\"}\r\n </p>\r\n </div>\r\n )}\r\n <div className=\"w-full\">\r\n {fileDataList.map((file) => (\r\n <div\r\n key={file.id}\r\n className=\"w-full flex items-center justify-between py-2 border-b \"\r\n >\r\n <div className=\"flex items-center content-center\">\r\n <MdInsertDriveFile style={{ fontSize: \"2rem\" }} />\r\n <a\r\n href={`/api/files/download/${file.id}`}\r\n className=\"pl-2 text-left underline text-primary\"\r\n target=\"_blank\"\r\n >\r\n {file.filename}\r\n </a>\r\n </div>\r\n {!disabled && file.readonly !== true && (\r\n <div\r\n onClick={() => handleRemove(file.id)}\r\n className=\"text-gray-600 cursor-pointer hover:text-primary hover:bg-gray-200 rounded-full ml-4\"\r\n >\r\n <MdDeleteOutline\r\n style={{ fontSize: \"1.5rem\", margin: \"10px\" }}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n {description && (\r\n <div\r\n className=\"HintText self-stretch text-slate-600 text-sm font-normal leading-tight\"\r\n id={name + \":description\"}\r\n >\r\n {description}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport default FileInputMultiple;\r\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import React__default from "react";
|
|
4
|
+
import { S as Slot } from "./index-D9mvqz1C.js";
|
|
5
|
+
import { cn } from "./utils/utils.js";
|
|
6
|
+
import { Label } from "./components/ui/label.js";
|
|
7
|
+
var isCheckBoxInput = (element) => element.type === "checkbox";
|
|
8
|
+
var isDateObject = (value) => value instanceof Date;
|
|
9
|
+
var isNullOrUndefined = (value) => value == null;
|
|
10
|
+
const isObjectType = (value) => typeof value === "object";
|
|
11
|
+
var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value);
|
|
12
|
+
var getEventValue = (event) => isObject(event) && event.target ? isCheckBoxInput(event.target) ? event.target.checked : event.target.value : event;
|
|
13
|
+
var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
|
|
14
|
+
var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
|
|
15
|
+
var isPlainObject = (tempObject) => {
|
|
16
|
+
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
|
17
|
+
return isObject(prototypeCopy) && prototypeCopy.hasOwnProperty("isPrototypeOf");
|
|
18
|
+
};
|
|
19
|
+
var isWeb = typeof window !== "undefined" && typeof window.HTMLElement !== "undefined" && typeof document !== "undefined";
|
|
20
|
+
function cloneObject(data) {
|
|
21
|
+
let copy;
|
|
22
|
+
const isArray = Array.isArray(data);
|
|
23
|
+
if (data instanceof Date) {
|
|
24
|
+
copy = new Date(data);
|
|
25
|
+
} else if (data instanceof Set) {
|
|
26
|
+
copy = new Set(data);
|
|
27
|
+
} else if (!(isWeb && (data instanceof Blob || data instanceof FileList)) && (isArray || isObject(data))) {
|
|
28
|
+
copy = isArray ? [] : {};
|
|
29
|
+
if (!isArray && !isPlainObject(data)) {
|
|
30
|
+
copy = data;
|
|
31
|
+
} else {
|
|
32
|
+
for (const key in data) {
|
|
33
|
+
if (data.hasOwnProperty(key)) {
|
|
34
|
+
copy[key] = cloneObject(data[key]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
return data;
|
|
40
|
+
}
|
|
41
|
+
return copy;
|
|
42
|
+
}
|
|
43
|
+
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
|
44
|
+
var isUndefined = (val) => val === void 0;
|
|
45
|
+
var get = (object, path, defaultValue) => {
|
|
46
|
+
if (!path || !isObject(object)) {
|
|
47
|
+
return defaultValue;
|
|
48
|
+
}
|
|
49
|
+
const result = compact(path.split(/[,[\].]+?/)).reduce((result2, key) => isNullOrUndefined(result2) ? result2 : result2[key], object);
|
|
50
|
+
return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
|
|
51
|
+
};
|
|
52
|
+
var isBoolean = (value) => typeof value === "boolean";
|
|
53
|
+
var isKey = (value) => /^\w*$/.test(value);
|
|
54
|
+
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/));
|
|
55
|
+
var set = (object, path, value) => {
|
|
56
|
+
let index = -1;
|
|
57
|
+
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
|
58
|
+
const length = tempPath.length;
|
|
59
|
+
const lastIndex = length - 1;
|
|
60
|
+
while (++index < length) {
|
|
61
|
+
const key = tempPath[index];
|
|
62
|
+
let newValue = value;
|
|
63
|
+
if (index !== lastIndex) {
|
|
64
|
+
const objValue = object[key];
|
|
65
|
+
newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) ? [] : {};
|
|
66
|
+
}
|
|
67
|
+
if (key === "__proto__") {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
object[key] = newValue;
|
|
71
|
+
object = object[key];
|
|
72
|
+
}
|
|
73
|
+
return object;
|
|
74
|
+
};
|
|
75
|
+
const EVENTS = {
|
|
76
|
+
BLUR: "blur",
|
|
77
|
+
FOCUS_OUT: "focusout",
|
|
78
|
+
CHANGE: "change"
|
|
79
|
+
};
|
|
80
|
+
const VALIDATION_MODE = {
|
|
81
|
+
onBlur: "onBlur",
|
|
82
|
+
onChange: "onChange",
|
|
83
|
+
onSubmit: "onSubmit",
|
|
84
|
+
onTouched: "onTouched",
|
|
85
|
+
all: "all"
|
|
86
|
+
};
|
|
87
|
+
const HookFormContext = React__default.createContext(null);
|
|
88
|
+
const useFormContext = () => React__default.useContext(HookFormContext);
|
|
89
|
+
const FormProvider = (props) => {
|
|
90
|
+
const { children, ...data } = props;
|
|
91
|
+
return React__default.createElement(HookFormContext.Provider, { value: data }, children);
|
|
92
|
+
};
|
|
93
|
+
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
|
94
|
+
const result = {
|
|
95
|
+
defaultValues: control._defaultValues
|
|
96
|
+
};
|
|
97
|
+
for (const key in formState) {
|
|
98
|
+
Object.defineProperty(result, key, {
|
|
99
|
+
get: () => {
|
|
100
|
+
const _key = key;
|
|
101
|
+
if (control._proxyFormState[_key] !== VALIDATION_MODE.all) {
|
|
102
|
+
control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
|
|
103
|
+
}
|
|
104
|
+
localProxyFormState && (localProxyFormState[_key] = true);
|
|
105
|
+
return formState[_key];
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
};
|
|
111
|
+
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
|
112
|
+
var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
|
|
113
|
+
updateFormState(formStateData);
|
|
114
|
+
const { name, ...formState } = formStateData;
|
|
115
|
+
return isEmptyObject(formState) || Object.keys(formState).length >= Object.keys(_proxyFormState).length || Object.keys(formState).find((key) => _proxyFormState[key] === !isRoot);
|
|
116
|
+
};
|
|
117
|
+
var convertToArrayPayload = (value) => Array.isArray(value) ? value : [value];
|
|
118
|
+
var shouldSubscribeByName = (name, signalName, exact) => !name || !signalName || name === signalName || convertToArrayPayload(name).some((currentName) => currentName && (exact ? currentName === signalName : currentName.startsWith(signalName) || signalName.startsWith(currentName)));
|
|
119
|
+
function useSubscribe(props) {
|
|
120
|
+
const _props = React__default.useRef(props);
|
|
121
|
+
_props.current = props;
|
|
122
|
+
React__default.useEffect(() => {
|
|
123
|
+
const subscription = !props.disabled && _props.current.subject && _props.current.subject.subscribe({
|
|
124
|
+
next: _props.current.next
|
|
125
|
+
});
|
|
126
|
+
return () => {
|
|
127
|
+
subscription && subscription.unsubscribe();
|
|
128
|
+
};
|
|
129
|
+
}, [props.disabled]);
|
|
130
|
+
}
|
|
131
|
+
function useFormState(props) {
|
|
132
|
+
const methods = useFormContext();
|
|
133
|
+
const { control = methods.control, disabled, name, exact } = props || {};
|
|
134
|
+
const [formState, updateFormState] = React__default.useState(control._formState);
|
|
135
|
+
const _mounted = React__default.useRef(true);
|
|
136
|
+
const _localProxyFormState = React__default.useRef({
|
|
137
|
+
isDirty: false,
|
|
138
|
+
isLoading: false,
|
|
139
|
+
dirtyFields: false,
|
|
140
|
+
touchedFields: false,
|
|
141
|
+
validatingFields: false,
|
|
142
|
+
isValidating: false,
|
|
143
|
+
isValid: false,
|
|
144
|
+
errors: false
|
|
145
|
+
});
|
|
146
|
+
const _name = React__default.useRef(name);
|
|
147
|
+
_name.current = name;
|
|
148
|
+
useSubscribe({
|
|
149
|
+
disabled,
|
|
150
|
+
next: (value) => _mounted.current && shouldSubscribeByName(_name.current, value.name, exact) && shouldRenderFormState(value, _localProxyFormState.current, control._updateFormState) && updateFormState({
|
|
151
|
+
...control._formState,
|
|
152
|
+
...value
|
|
153
|
+
}),
|
|
154
|
+
subject: control._subjects.state
|
|
155
|
+
});
|
|
156
|
+
React__default.useEffect(() => {
|
|
157
|
+
_mounted.current = true;
|
|
158
|
+
_localProxyFormState.current.isValid && control._updateValid(true);
|
|
159
|
+
return () => {
|
|
160
|
+
_mounted.current = false;
|
|
161
|
+
};
|
|
162
|
+
}, [control]);
|
|
163
|
+
return getProxyFormState(formState, control, _localProxyFormState.current, false);
|
|
164
|
+
}
|
|
165
|
+
var isString = (value) => typeof value === "string";
|
|
166
|
+
var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
|
|
167
|
+
if (isString(names)) {
|
|
168
|
+
return get(formValues, names, defaultValue);
|
|
169
|
+
}
|
|
170
|
+
if (Array.isArray(names)) {
|
|
171
|
+
return names.map((fieldName) => get(formValues, fieldName));
|
|
172
|
+
}
|
|
173
|
+
return formValues;
|
|
174
|
+
};
|
|
175
|
+
function useWatch(props) {
|
|
176
|
+
const methods = useFormContext();
|
|
177
|
+
const { control = methods.control, name, defaultValue, disabled, exact } = props || {};
|
|
178
|
+
const _name = React__default.useRef(name);
|
|
179
|
+
_name.current = name;
|
|
180
|
+
useSubscribe({
|
|
181
|
+
disabled,
|
|
182
|
+
subject: control._subjects.values,
|
|
183
|
+
next: (formState) => {
|
|
184
|
+
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
|
185
|
+
updateValue(cloneObject(generateWatchOutput(_name.current, control._names, formState.values || control._formValues, false, defaultValue)));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
const [value, updateValue] = React__default.useState(control._getWatch(name, defaultValue));
|
|
190
|
+
React__default.useEffect(() => control._removeUnmounted());
|
|
191
|
+
return value;
|
|
192
|
+
}
|
|
193
|
+
function useController(props) {
|
|
194
|
+
const methods = useFormContext();
|
|
195
|
+
const { name, disabled, control = methods.control, shouldUnregister } = props;
|
|
196
|
+
const isArrayField = isNameInFieldArray(control._names.array, name);
|
|
197
|
+
const value = useWatch({
|
|
198
|
+
control,
|
|
199
|
+
name,
|
|
200
|
+
defaultValue: get(control._formValues, name, get(control._defaultValues, name, props.defaultValue)),
|
|
201
|
+
exact: true
|
|
202
|
+
});
|
|
203
|
+
const formState = useFormState({
|
|
204
|
+
control,
|
|
205
|
+
name,
|
|
206
|
+
exact: true
|
|
207
|
+
});
|
|
208
|
+
const _registerProps = React__default.useRef(control.register(name, {
|
|
209
|
+
...props.rules,
|
|
210
|
+
value,
|
|
211
|
+
...isBoolean(props.disabled) ? { disabled: props.disabled } : {}
|
|
212
|
+
}));
|
|
213
|
+
React__default.useEffect(() => {
|
|
214
|
+
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
|
215
|
+
const updateMounted = (name2, value2) => {
|
|
216
|
+
const field = get(control._fields, name2);
|
|
217
|
+
if (field && field._f) {
|
|
218
|
+
field._f.mount = value2;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
updateMounted(name, true);
|
|
222
|
+
if (_shouldUnregisterField) {
|
|
223
|
+
const value2 = cloneObject(get(control._options.defaultValues, name));
|
|
224
|
+
set(control._defaultValues, name, value2);
|
|
225
|
+
if (isUndefined(get(control._formValues, name))) {
|
|
226
|
+
set(control._formValues, name, value2);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return () => {
|
|
230
|
+
(isArrayField ? _shouldUnregisterField && !control._state.action : _shouldUnregisterField) ? control.unregister(name) : updateMounted(name, false);
|
|
231
|
+
};
|
|
232
|
+
}, [name, control, isArrayField, shouldUnregister]);
|
|
233
|
+
React__default.useEffect(() => {
|
|
234
|
+
if (get(control._fields, name)) {
|
|
235
|
+
control._updateDisabledField({
|
|
236
|
+
disabled,
|
|
237
|
+
fields: control._fields,
|
|
238
|
+
name,
|
|
239
|
+
value: get(control._fields, name)._f.value
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}, [disabled, name, control]);
|
|
243
|
+
return {
|
|
244
|
+
field: {
|
|
245
|
+
name,
|
|
246
|
+
value,
|
|
247
|
+
...isBoolean(disabled) || formState.disabled ? { disabled: formState.disabled || disabled } : {},
|
|
248
|
+
onChange: React__default.useCallback((event) => _registerProps.current.onChange({
|
|
249
|
+
target: {
|
|
250
|
+
value: getEventValue(event),
|
|
251
|
+
name
|
|
252
|
+
},
|
|
253
|
+
type: EVENTS.CHANGE
|
|
254
|
+
}), [name]),
|
|
255
|
+
onBlur: React__default.useCallback(() => _registerProps.current.onBlur({
|
|
256
|
+
target: {
|
|
257
|
+
value: get(control._formValues, name),
|
|
258
|
+
name
|
|
259
|
+
},
|
|
260
|
+
type: EVENTS.BLUR
|
|
261
|
+
}), [name, control]),
|
|
262
|
+
ref: React__default.useCallback((elm) => {
|
|
263
|
+
const field = get(control._fields, name);
|
|
264
|
+
if (field && elm) {
|
|
265
|
+
field._f.ref = {
|
|
266
|
+
focus: () => elm.focus(),
|
|
267
|
+
select: () => elm.select(),
|
|
268
|
+
setCustomValidity: (message) => elm.setCustomValidity(message),
|
|
269
|
+
reportValidity: () => elm.reportValidity()
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
}, [control._fields, name])
|
|
273
|
+
},
|
|
274
|
+
formState,
|
|
275
|
+
fieldState: Object.defineProperties({}, {
|
|
276
|
+
invalid: {
|
|
277
|
+
enumerable: true,
|
|
278
|
+
get: () => !!get(formState.errors, name)
|
|
279
|
+
},
|
|
280
|
+
isDirty: {
|
|
281
|
+
enumerable: true,
|
|
282
|
+
get: () => !!get(formState.dirtyFields, name)
|
|
283
|
+
},
|
|
284
|
+
isTouched: {
|
|
285
|
+
enumerable: true,
|
|
286
|
+
get: () => !!get(formState.touchedFields, name)
|
|
287
|
+
},
|
|
288
|
+
isValidating: {
|
|
289
|
+
enumerable: true,
|
|
290
|
+
get: () => !!get(formState.validatingFields, name)
|
|
291
|
+
},
|
|
292
|
+
error: {
|
|
293
|
+
enumerable: true,
|
|
294
|
+
get: () => get(formState.errors, name)
|
|
295
|
+
}
|
|
296
|
+
})
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
const Controller = (props) => props.render(useController(props));
|
|
300
|
+
const Form = FormProvider;
|
|
301
|
+
const FormFieldContext = React.createContext(
|
|
302
|
+
{}
|
|
303
|
+
);
|
|
304
|
+
const FormField = ({
|
|
305
|
+
...props
|
|
306
|
+
}) => {
|
|
307
|
+
return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
|
|
308
|
+
};
|
|
309
|
+
const useFormField = () => {
|
|
310
|
+
const fieldContext = React.useContext(FormFieldContext);
|
|
311
|
+
const itemContext = React.useContext(FormItemContext);
|
|
312
|
+
const { getFieldState, formState } = useFormContext();
|
|
313
|
+
const fieldState = getFieldState(fieldContext.name, formState);
|
|
314
|
+
if (!fieldContext) {
|
|
315
|
+
throw new Error("useFormField should be used within <FormField>");
|
|
316
|
+
}
|
|
317
|
+
const { id } = itemContext;
|
|
318
|
+
return {
|
|
319
|
+
id,
|
|
320
|
+
name: fieldContext.name,
|
|
321
|
+
formItemId: `${id}-form-item`,
|
|
322
|
+
formDescriptionId: `${id}-form-item-description`,
|
|
323
|
+
formMessageId: `${id}-form-item-message`,
|
|
324
|
+
...fieldState
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
const FormItemContext = React.createContext(
|
|
328
|
+
{}
|
|
329
|
+
);
|
|
330
|
+
const FormItem = React.forwardRef(({ className, ...props }, ref) => {
|
|
331
|
+
const id = React.useId();
|
|
332
|
+
return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx("div", { ref, className: cn("space-y-2", className), ...props }) });
|
|
333
|
+
});
|
|
334
|
+
FormItem.displayName = "FormItem";
|
|
335
|
+
const FormLabel = React.forwardRef(({ className, ...props }, ref) => {
|
|
336
|
+
const { error, formItemId } = useFormField();
|
|
337
|
+
return /* @__PURE__ */ jsx(
|
|
338
|
+
Label,
|
|
339
|
+
{
|
|
340
|
+
ref,
|
|
341
|
+
className: cn(error && "text-destructive", className),
|
|
342
|
+
htmlFor: formItemId,
|
|
343
|
+
...props
|
|
344
|
+
}
|
|
345
|
+
);
|
|
346
|
+
});
|
|
347
|
+
FormLabel.displayName = "FormLabel";
|
|
348
|
+
const FormControl = React.forwardRef(({ ...props }, ref) => {
|
|
349
|
+
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
350
|
+
return /* @__PURE__ */ jsx(
|
|
351
|
+
Slot,
|
|
352
|
+
{
|
|
353
|
+
ref,
|
|
354
|
+
id: formItemId,
|
|
355
|
+
"aria-describedby": !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`,
|
|
356
|
+
"aria-invalid": !!error,
|
|
357
|
+
...props
|
|
358
|
+
}
|
|
359
|
+
);
|
|
360
|
+
});
|
|
361
|
+
FormControl.displayName = "FormControl";
|
|
362
|
+
const FormDescription = React.forwardRef(({ className, ...props }, ref) => {
|
|
363
|
+
const { formDescriptionId } = useFormField();
|
|
364
|
+
return /* @__PURE__ */ jsx(
|
|
365
|
+
"p",
|
|
366
|
+
{
|
|
367
|
+
ref,
|
|
368
|
+
id: formDescriptionId,
|
|
369
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
370
|
+
...props
|
|
371
|
+
}
|
|
372
|
+
);
|
|
373
|
+
});
|
|
374
|
+
FormDescription.displayName = "FormDescription";
|
|
375
|
+
const FormMessage = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
376
|
+
const { error, formMessageId } = useFormField();
|
|
377
|
+
const body = error ? String(error == null ? void 0 : error.message) : children;
|
|
378
|
+
if (!body) {
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
return /* @__PURE__ */ jsx(
|
|
382
|
+
"p",
|
|
383
|
+
{
|
|
384
|
+
ref,
|
|
385
|
+
id: formMessageId,
|
|
386
|
+
className: cn("text-sm font-medium text-destructive", className),
|
|
387
|
+
...props,
|
|
388
|
+
children: body
|
|
389
|
+
}
|
|
390
|
+
);
|
|
391
|
+
});
|
|
392
|
+
FormMessage.displayName = "FormMessage";
|
|
393
|
+
export {
|
|
394
|
+
Form as F,
|
|
395
|
+
FormItem as a,
|
|
396
|
+
FormLabel as b,
|
|
397
|
+
FormControl as c,
|
|
398
|
+
FormDescription as d,
|
|
399
|
+
FormMessage as e,
|
|
400
|
+
FormField as f,
|
|
401
|
+
useFormState as g,
|
|
402
|
+
useFormField as u
|
|
403
|
+
};
|
|
404
|
+
//# sourceMappingURL=form-Bb28hcCd.js.map
|