@addsign/moje-agenda-shared-lib 2.0.72 → 2.0.73
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/Dialog-BmQoVu5C.js.map +1 -1
- package/dist/assets/style.css +1772 -1758
- package/dist/components/Attachments.js +2 -2
- package/dist/components/datatable/DataTable.js +3 -3
- package/dist/components/datatable/DataTableServer.js +3 -3
- package/dist/components/form/AutocompleteSearchBar.js +2 -2
- package/dist/components/form/AutocompleteSearchBarServer.js +2 -2
- package/dist/components/form/FileInput.js +3 -3
- package/dist/components/form/FileInputForm.d.ts +1 -0
- package/dist/components/form/FileInputForm.js +201 -93
- package/dist/components/form/FileInputForm.js.map +1 -1
- package/dist/components/form/FileInputFormMultiple.d.ts +1 -0
- package/dist/components/form/FileInputFormMultiple.js +203 -82
- package/dist/components/form/FileInputFormMultiple.js.map +1 -1
- package/dist/components/form/FileInputMultiple.js +3 -3
- package/dist/components/form/FormField.js +2 -2
- package/dist/components/form/PositionsSelectorSingle.js +3 -3
- package/dist/components/form/SelectField.js +2 -2
- package/dist/components/layout/Neoptimizovano.js +2 -2
- package/dist/components/profiles/ProfileOverview.js +2 -2
- package/dist/components/ui/Combobox.js +1 -1
- package/dist/components/ui/DatePicker.js +2 -2
- package/dist/components/ui/DateTimePicker.js +2 -2
- package/dist/components/ui/Dialog.js +1 -1
- package/dist/components/ui/ScrollArea.js +2 -2
- package/dist/components/ui/checkbox.js +4 -4
- package/dist/components/ui/command.d.ts +6 -6
- package/dist/components/ui/command.js +2 -2
- package/dist/components/ui/input.js +8 -107
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/multi-select.js +1 -1
- package/dist/components/ui/popover.js +1 -1
- package/dist/components/ui/radioGroup.js +5 -5
- package/dist/components/ui/select.js +7 -7
- package/dist/components/ui/toast.js +5 -5
- package/dist/components/ui/tooltip.js +6 -6
- package/dist/input-Cm_FjJOF.js +111 -0
- package/dist/input-Cm_FjJOF.js.map +1 -0
- package/dist/main.js +3 -3
- package/dist/popover-DpJhfyvx.js.map +1 -1
- package/lib/components/form/FileInputForm.tsx +245 -99
- package/lib/components/form/FileInputFormMultiple.tsx +233 -65
- package/lib/css/tailwind.css +9 -9
- package/package.json +1 -1
- package/tailwind.config.js +97 -97
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import "../tailwind-l0sNRNKZ.js";
|
|
3
3
|
import "react";
|
|
4
|
+
import "../Dialog-BmQoVu5C.js";
|
|
5
|
+
import "../input-Cm_FjJOF.js";
|
|
4
6
|
import "./ui/button.js";
|
|
5
|
-
import "./ui/input.js";
|
|
6
7
|
import "./ui/multi-select.js";
|
|
7
8
|
import "./ui/select.js";
|
|
8
9
|
import "../index.esm-ifS8v9eQ.js";
|
|
9
10
|
import "../jspdf.plugin.autotable-7hp3hM-a.js";
|
|
10
11
|
import "../contexts/FederationContext.js";
|
|
11
12
|
import { getFullNameList } from "../utils/getFullName.js";
|
|
12
|
-
import "../Dialog-CCrUyF91.js";
|
|
13
13
|
import "./ui/ScrollArea.js";
|
|
14
14
|
import "./ui/form.js";
|
|
15
15
|
import "./ui/radioGroup.js";
|
|
@@ -4,15 +4,15 @@ import "../../tailwind-l0sNRNKZ.js";
|
|
|
4
4
|
import Button from "../Button.js";
|
|
5
5
|
import { f as MdOutlineFilterAlt, g as MdOutlineFilterAltOff, h as MdSearch, b as MdClose, i as MdArrowBack, j as MdArrowForward, k as MdArrowUpward, l as MdArrowDownward } from "../../index-CrfjcbOs.js";
|
|
6
6
|
import FormField from "../form/FormField.js";
|
|
7
|
-
import
|
|
7
|
+
import "../../Dialog-BmQoVu5C.js";
|
|
8
|
+
import "../../input-Cm_FjJOF.js";
|
|
8
9
|
import "../ui/button.js";
|
|
9
|
-
import "../
|
|
10
|
+
import Spinner from "../Spinner.js";
|
|
10
11
|
import "../ui/multi-select.js";
|
|
11
12
|
import "../ui/select.js";
|
|
12
13
|
import "../../index.esm-ifS8v9eQ.js";
|
|
13
14
|
import "../../jspdf.plugin.autotable-7hp3hM-a.js";
|
|
14
15
|
import "../../contexts/FederationContext.js";
|
|
15
|
-
import "../../Dialog-CCrUyF91.js";
|
|
16
16
|
import "../ui/ScrollArea.js";
|
|
17
17
|
import "../ui/form.js";
|
|
18
18
|
import "../ui/radioGroup.js";
|
|
@@ -4,17 +4,17 @@ import "../../tailwind-l0sNRNKZ.js";
|
|
|
4
4
|
import Button from "../Button.js";
|
|
5
5
|
import { f as MdOutlineFilterAlt, g as MdOutlineFilterAltOff, h as MdSearch, b as MdClose, i as MdArrowBack, j as MdArrowForward, k as MdArrowUpward, l as MdArrowDownward, n as MdOutlineUnfoldMore } from "../../index-CrfjcbOs.js";
|
|
6
6
|
import FormField from "../form/FormField.js";
|
|
7
|
-
import
|
|
7
|
+
import "../../Dialog-BmQoVu5C.js";
|
|
8
|
+
import { I as Input } from "../../input-Cm_FjJOF.js";
|
|
8
9
|
import "../ui/button.js";
|
|
10
|
+
import Spinner from "../Spinner.js";
|
|
9
11
|
import DateRangeField from "../form/DateRangeField.js";
|
|
10
12
|
import DateField from "../form/DateField.js";
|
|
11
13
|
import "../../jspdf.plugin.autotable-7hp3hM-a.js";
|
|
12
14
|
import "../../contexts/FederationContext.js";
|
|
13
15
|
import { useFederationContext } from "../../contexts/useFederationContext.js";
|
|
14
16
|
import { handleErrors } from "../../utils/handleErrors.js";
|
|
15
|
-
import "../../Dialog-CCrUyF91.js";
|
|
16
17
|
import "../ui/ScrollArea.js";
|
|
17
|
-
import { Input } from "../ui/input.js";
|
|
18
18
|
import "../ui/form.js";
|
|
19
19
|
import "../ui/radioGroup.js";
|
|
20
20
|
import "../ui/command.js";
|
|
@@ -2,15 +2,15 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useRef, useEffect } from "react";
|
|
3
3
|
import "../../tailwind-l0sNRNKZ.js";
|
|
4
4
|
import { M as MdExpandLess, a as MdExpandMore, b as MdClose } from "../../index-CrfjcbOs.js";
|
|
5
|
+
import "../../Dialog-BmQoVu5C.js";
|
|
6
|
+
import "../../input-Cm_FjJOF.js";
|
|
5
7
|
import "../ui/button.js";
|
|
6
|
-
import "../ui/input.js";
|
|
7
8
|
import "../ui/multi-select.js";
|
|
8
9
|
import "../ui/select.js";
|
|
9
10
|
import "../../index.esm-ifS8v9eQ.js";
|
|
10
11
|
import "../../jspdf.plugin.autotable-7hp3hM-a.js";
|
|
11
12
|
import "../../contexts/FederationContext.js";
|
|
12
13
|
import { useFederationContext } from "../../contexts/useFederationContext.js";
|
|
13
|
-
import "../../Dialog-CCrUyF91.js";
|
|
14
14
|
import "../ui/ScrollArea.js";
|
|
15
15
|
import "../ui/form.js";
|
|
16
16
|
import "../ui/radioGroup.js";
|
|
@@ -3,15 +3,15 @@ import { useState, useRef, useEffect } from "react";
|
|
|
3
3
|
import { M as MdExpandLess } from "../../index-CrfjcbOs.js";
|
|
4
4
|
import "../../tailwind-l0sNRNKZ.js";
|
|
5
5
|
import InputField from "./InputField.js";
|
|
6
|
+
import "../../Dialog-BmQoVu5C.js";
|
|
7
|
+
import "../../input-Cm_FjJOF.js";
|
|
6
8
|
import "../ui/button.js";
|
|
7
|
-
import "../ui/input.js";
|
|
8
9
|
import "../ui/multi-select.js";
|
|
9
10
|
import "../ui/select.js";
|
|
10
11
|
import "../../index.esm-ifS8v9eQ.js";
|
|
11
12
|
import "../../jspdf.plugin.autotable-7hp3hM-a.js";
|
|
12
13
|
import "../../contexts/FederationContext.js";
|
|
13
14
|
import { useFederationContext } from "../../contexts/useFederationContext.js";
|
|
14
|
-
import "../../Dialog-CCrUyF91.js";
|
|
15
15
|
import "../ui/ScrollArea.js";
|
|
16
16
|
import "../ui/form.js";
|
|
17
17
|
import "../ui/radioGroup.js";
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect, useCallback } from "react";
|
|
3
|
-
import { u as useDropzone } from "../../index-
|
|
3
|
+
import { u as useDropzone } from "../../index-DrJcw1yx.js";
|
|
4
4
|
import "../../tailwind-l0sNRNKZ.js";
|
|
5
5
|
import { d as MdInsertDriveFile, e as MdDeleteOutline } from "../../index-CrfjcbOs.js";
|
|
6
6
|
import { cn } from "../../utils/utils.js";
|
|
7
|
+
import "../../Dialog-BmQoVu5C.js";
|
|
8
|
+
import "../../input-Cm_FjJOF.js";
|
|
7
9
|
import "../ui/button.js";
|
|
8
|
-
import "../ui/input.js";
|
|
9
10
|
import "../ui/multi-select.js";
|
|
10
11
|
import "../ui/select.js";
|
|
11
12
|
import "../../index.esm-ifS8v9eQ.js";
|
|
@@ -13,7 +14,6 @@ import "../../jspdf.plugin.autotable-7hp3hM-a.js";
|
|
|
13
14
|
import "../../contexts/FederationContext.js";
|
|
14
15
|
import { useFederationContext } from "../../contexts/useFederationContext.js";
|
|
15
16
|
import { handleErrors } from "../../utils/handleErrors.js";
|
|
16
|
-
import "../../Dialog-CCrUyF91.js";
|
|
17
17
|
import "../ui/ScrollArea.js";
|
|
18
18
|
import "../ui/form.js";
|
|
19
19
|
import "../ui/radioGroup.js";
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect, useCallback } from "react";
|
|
3
|
-
import { u as useDropzone } from "../../index-
|
|
3
|
+
import { u as useDropzone } from "../../index-DrJcw1yx.js";
|
|
4
4
|
import { d as MdInsertDriveFile, e as MdDeleteOutline } from "../../index-CrfjcbOs.js";
|
|
5
5
|
import { cn } from "../../utils/utils.js";
|
|
6
6
|
import "../../tailwind-l0sNRNKZ.js";
|
|
7
|
-
import "
|
|
8
|
-
import "
|
|
7
|
+
import { D as Dialog, e as DialogContent, f as DialogHeader, h as DialogTitle, g as DialogFooter } from "../../Dialog-BmQoVu5C.js";
|
|
8
|
+
import { L as LoaderCircle, I as Input } from "../../input-Cm_FjJOF.js";
|
|
9
|
+
import { Button } from "../ui/button.js";
|
|
9
10
|
import "../ui/multi-select.js";
|
|
10
11
|
import "../ui/select.js";
|
|
11
12
|
import "../../index.esm-ifS8v9eQ.js";
|
|
@@ -13,7 +14,6 @@ import "../../jspdf.plugin.autotable-7hp3hM-a.js";
|
|
|
13
14
|
import "../../contexts/FederationContext.js";
|
|
14
15
|
import { useFederationContext } from "../../contexts/useFederationContext.js";
|
|
15
16
|
import { handleErrors } from "../../utils/handleErrors.js";
|
|
16
|
-
import "../../Dialog-CCrUyF91.js";
|
|
17
17
|
import "../ui/ScrollArea.js";
|
|
18
18
|
import { useFormField } from "../ui/form.js";
|
|
19
19
|
import "../ui/radioGroup.js";
|
|
@@ -34,16 +34,73 @@ const FileInputForm = ({
|
|
|
34
34
|
description,
|
|
35
35
|
disabled,
|
|
36
36
|
attachmentName,
|
|
37
|
-
attachmentType
|
|
37
|
+
attachmentType,
|
|
38
|
+
askForAttachmentName = false
|
|
38
39
|
}) => {
|
|
39
40
|
const [fileData, setFileData] = useState(value || null);
|
|
40
41
|
const [isFocused, setIsFocused] = useState(false);
|
|
42
|
+
const [pendingFile, setPendingFile] = useState(null);
|
|
43
|
+
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
44
|
+
const [fileName, setFileName] = useState("");
|
|
45
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
41
46
|
const federationContext = useFederationContext();
|
|
42
47
|
const { error } = useFormField();
|
|
43
48
|
const hasError = !!error;
|
|
44
49
|
useEffect(() => {
|
|
45
50
|
setFileData(value || null);
|
|
46
51
|
}, [value]);
|
|
52
|
+
const uploadFile = useCallback(
|
|
53
|
+
async (file, customName) => {
|
|
54
|
+
if (file.size > MAX_FILE_SIZE) {
|
|
55
|
+
federationContext.emitter.emit("message", {
|
|
56
|
+
title: "Velikost souboru byla překročena",
|
|
57
|
+
message: `Maximální povolená velikost je ${MAX_FILE_SIZE / (1024 * 1024)} MB.`,
|
|
58
|
+
classes: "bg-danger ",
|
|
59
|
+
timeout: 0,
|
|
60
|
+
type: "error"
|
|
61
|
+
});
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
setIsUploading(true);
|
|
65
|
+
const formData = new FormData();
|
|
66
|
+
const dataObject = {
|
|
67
|
+
...customName ? { attachmentName: customName } : attachmentName && { attachmentName },
|
|
68
|
+
...attachmentType && { attachmentType }
|
|
69
|
+
};
|
|
70
|
+
formData.append(
|
|
71
|
+
"data",
|
|
72
|
+
new Blob([JSON.stringify(dataObject)], { type: "application/json" })
|
|
73
|
+
);
|
|
74
|
+
formData.append("file", file);
|
|
75
|
+
try {
|
|
76
|
+
const response = await federationContext.apiClient.post(
|
|
77
|
+
"/files/upload",
|
|
78
|
+
formData,
|
|
79
|
+
{
|
|
80
|
+
headers: {
|
|
81
|
+
"Content-Type": "multipart/form-data"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
const uploadedFile = response.data;
|
|
86
|
+
setFileData(uploadedFile);
|
|
87
|
+
onFileChanged(uploadedFile);
|
|
88
|
+
setIsFocused(false);
|
|
89
|
+
} catch (error2) {
|
|
90
|
+
handleErrors(error2, federationContext.emitter);
|
|
91
|
+
console.error("There was an error!", error2);
|
|
92
|
+
} finally {
|
|
93
|
+
setIsUploading(false);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
[
|
|
97
|
+
federationContext.apiClient,
|
|
98
|
+
federationContext.emitter,
|
|
99
|
+
onFileChanged,
|
|
100
|
+
attachmentName,
|
|
101
|
+
attachmentType
|
|
102
|
+
]
|
|
103
|
+
);
|
|
47
104
|
const onDrop = useCallback(
|
|
48
105
|
async (acceptedFiles) => {
|
|
49
106
|
if (acceptedFiles.length > 0) {
|
|
@@ -58,111 +115,162 @@ const FileInputForm = ({
|
|
|
58
115
|
});
|
|
59
116
|
return;
|
|
60
117
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
"data",
|
|
68
|
-
new Blob([JSON.stringify(dataObject)], { type: "application/json" })
|
|
69
|
-
);
|
|
70
|
-
formData.append("file", file);
|
|
71
|
-
try {
|
|
72
|
-
const response = await federationContext.apiClient.post(
|
|
73
|
-
"/files/upload",
|
|
74
|
-
formData,
|
|
75
|
-
{
|
|
76
|
-
headers: {
|
|
77
|
-
"Content-Type": "multipart/form-data"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
);
|
|
81
|
-
const uploadedFile = response.data;
|
|
82
|
-
setFileData(uploadedFile);
|
|
83
|
-
onFileChanged(uploadedFile);
|
|
84
|
-
setIsFocused(false);
|
|
85
|
-
} catch (error2) {
|
|
86
|
-
handleErrors(error2, federationContext.emitter);
|
|
87
|
-
console.error("There was an error!", error2);
|
|
118
|
+
if (askForAttachmentName) {
|
|
119
|
+
setPendingFile(file);
|
|
120
|
+
setFileName(file.name);
|
|
121
|
+
setIsDialogOpen(true);
|
|
122
|
+
} else {
|
|
123
|
+
await uploadFile(file);
|
|
88
124
|
}
|
|
89
125
|
}
|
|
90
126
|
},
|
|
91
|
-
[
|
|
92
|
-
federationContext.apiClient,
|
|
93
|
-
federationContext.emitter,
|
|
94
|
-
onFileChanged,
|
|
95
|
-
attachmentName,
|
|
96
|
-
attachmentType
|
|
97
|
-
]
|
|
127
|
+
[askForAttachmentName, uploadFile, federationContext]
|
|
98
128
|
);
|
|
129
|
+
const handleDialogSubmit = async () => {
|
|
130
|
+
if (pendingFile) {
|
|
131
|
+
setIsDialogOpen(false);
|
|
132
|
+
await uploadFile(pendingFile, fileName);
|
|
133
|
+
setPendingFile(null);
|
|
134
|
+
setFileName("");
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const handleDialogCancel = () => {
|
|
138
|
+
setIsDialogOpen(false);
|
|
139
|
+
setPendingFile(null);
|
|
140
|
+
setFileName("");
|
|
141
|
+
};
|
|
142
|
+
const formatFileSize = (bytes) => {
|
|
143
|
+
if (bytes === 0)
|
|
144
|
+
return "0 Bytes";
|
|
145
|
+
const k = 1024;
|
|
146
|
+
const sizes = ["Bytes", "KB", "MB", "GB"];
|
|
147
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
148
|
+
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
|
|
149
|
+
};
|
|
99
150
|
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
|
100
151
|
onDrop,
|
|
101
|
-
disabled,
|
|
152
|
+
disabled: disabled || isUploading,
|
|
102
153
|
multiple: false
|
|
103
154
|
});
|
|
104
155
|
const handleRemove = () => {
|
|
105
156
|
setFileData(null);
|
|
106
157
|
onFileChanged(null);
|
|
107
158
|
};
|
|
108
|
-
return /* @__PURE__ */ jsxs(
|
|
109
|
-
/* @__PURE__ */
|
|
110
|
-
"div",
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
]
|
|
130
|
-
}
|
|
131
|
-
) : /* @__PURE__ */ jsxs("div", { className: "w-full flex items-center justify-between", children: [
|
|
132
|
-
/* @__PURE__ */ jsxs("div", { className: " flex", children: [
|
|
133
|
-
/* @__PURE__ */ jsx(MdInsertDriveFile, { style: { fontSize: "2rem" } }),
|
|
134
|
-
/* @__PURE__ */ jsx(
|
|
135
|
-
"a",
|
|
159
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
160
|
+
/* @__PURE__ */ jsxs("div", { className: "w-full min-h-30 flex-col justify-start items-start gap-1.5 inline-flex sharedLibrary", children: [
|
|
161
|
+
/* @__PURE__ */ jsx("div", { className: "self-stretch flex-col justify-start items-start gap-1.5 flex", children: /* @__PURE__ */ jsxs(
|
|
162
|
+
"div",
|
|
163
|
+
{
|
|
164
|
+
className: cn(
|
|
165
|
+
`self-stretch px-2 py-2 rounded-lg justify-start items-center gap-2 inline-flex outline-none border relative`,
|
|
166
|
+
isFocused && !hasError && "outline-4 outline-indigo-200 outline-offset-0 border-indigo-300",
|
|
167
|
+
hasError && "outline-4 outline-red-200 outline-offset-0 border-none",
|
|
168
|
+
!isFocused && hasError && "border-red-200 ",
|
|
169
|
+
disabled ? "bg-gray-100" : "bg-transparent"
|
|
170
|
+
),
|
|
171
|
+
onFocus: () => setIsFocused(true),
|
|
172
|
+
onBlur: () => setIsFocused(false),
|
|
173
|
+
children: [
|
|
174
|
+
isUploading && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-sm rounded-lg z-10 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
175
|
+
/* @__PURE__ */ jsx(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" }),
|
|
176
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600", children: "Nahrávání..." })
|
|
177
|
+
] }) }),
|
|
178
|
+
/* @__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
|
+
"div",
|
|
136
180
|
{
|
|
137
|
-
|
|
138
|
-
className:
|
|
139
|
-
|
|
140
|
-
|
|
181
|
+
...getRootProps(),
|
|
182
|
+
className: cn(
|
|
183
|
+
`w-full p-4 border-dashed border-2 rounded-lg text-center`,
|
|
184
|
+
isUploading ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-gray-100",
|
|
185
|
+
isDragActive ? "border-indigo-300 bg-indigo-50" : "border-gray-300"
|
|
186
|
+
),
|
|
187
|
+
children: [
|
|
188
|
+
/* @__PURE__ */ jsx("input", { ...getInputProps(), id: name }),
|
|
189
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: isDragActive ? "Sem přetáhněte soubor" : "Klikněte pro nahrání, nebo nahrajte přetažením souboru" })
|
|
190
|
+
]
|
|
141
191
|
}
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
192
|
+
) : /* @__PURE__ */ jsxs("div", { className: "w-full flex items-center justify-between py-2 border-b", children: [
|
|
193
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col flex-1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
194
|
+
/* @__PURE__ */ jsx(MdInsertDriveFile, { style: { fontSize: "2rem" } }),
|
|
195
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1", children: [
|
|
196
|
+
/* @__PURE__ */ jsx(
|
|
197
|
+
"a",
|
|
198
|
+
{
|
|
199
|
+
href: `/api/files/download/${fileData.id}`,
|
|
200
|
+
className: "text-left underline text-primary text-sm cursor-pointer",
|
|
201
|
+
target: "_blank",
|
|
202
|
+
children: fileData.filename
|
|
203
|
+
}
|
|
204
|
+
),
|
|
205
|
+
fileData.attachmentName && /* @__PURE__ */ jsx("div", { className: "text-sm text-gray-600", children: fileData.attachmentName })
|
|
206
|
+
] })
|
|
207
|
+
] }) }),
|
|
208
|
+
!disabled && !isUploading && /* @__PURE__ */ jsx(
|
|
209
|
+
"div",
|
|
151
210
|
{
|
|
152
|
-
|
|
211
|
+
onClick: handleRemove,
|
|
212
|
+
className: "text-gray-600 cursor-pointer hover:text-primary hover:bg-gray-200 rounded-full ml-4",
|
|
213
|
+
children: /* @__PURE__ */ jsx(
|
|
214
|
+
MdDeleteOutline,
|
|
215
|
+
{
|
|
216
|
+
style: { fontSize: "1.5rem", margin: "15px" }
|
|
217
|
+
}
|
|
218
|
+
)
|
|
153
219
|
}
|
|
154
220
|
)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
221
|
+
] }) })
|
|
222
|
+
]
|
|
223
|
+
}
|
|
224
|
+
) }),
|
|
225
|
+
description && /* @__PURE__ */ jsx(
|
|
226
|
+
"div",
|
|
227
|
+
{
|
|
228
|
+
className: "HintText self-stretch text-slate-600 text-sm font-normal leading-tight",
|
|
229
|
+
id: name + ":description",
|
|
230
|
+
children: description
|
|
231
|
+
}
|
|
232
|
+
)
|
|
233
|
+
] }),
|
|
234
|
+
/* @__PURE__ */ jsx(
|
|
235
|
+
Dialog,
|
|
162
236
|
{
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
237
|
+
open: isDialogOpen,
|
|
238
|
+
onOpenChange: (open) => {
|
|
239
|
+
setIsDialogOpen(open);
|
|
240
|
+
if (!open) {
|
|
241
|
+
handleDialogCancel();
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-lg", children: [
|
|
245
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: "Zadejte popis přílohy" }) }),
|
|
246
|
+
pendingFile && /* @__PURE__ */ jsx("div", { className: "space-y-4 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 p-4 border rounded-lg", children: [
|
|
247
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
248
|
+
/* @__PURE__ */ jsx(MdInsertDriveFile, { style: { fontSize: "1.5rem" } }),
|
|
249
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
250
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium text-sm", children: pendingFile.name }),
|
|
251
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: formatFileSize(pendingFile.size) })
|
|
252
|
+
] })
|
|
253
|
+
] }),
|
|
254
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2", children: [
|
|
255
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium mb-1 block", children: "Popis přílohy:" }),
|
|
256
|
+
/* @__PURE__ */ jsx(
|
|
257
|
+
Input,
|
|
258
|
+
{
|
|
259
|
+
value: fileName,
|
|
260
|
+
onChange: (e) => setFileName(e.target.value),
|
|
261
|
+
placeholder: "Zadejte popis přílohy"
|
|
262
|
+
}
|
|
263
|
+
)
|
|
264
|
+
] })
|
|
265
|
+
] }) }),
|
|
266
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
267
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleDialogCancel, disabled: isUploading, children: "Zrušit" }),
|
|
268
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleDialogSubmit, disabled: isUploading, children: isUploading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
269
|
+
/* @__PURE__ */ jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2" }),
|
|
270
|
+
"Nahrávání..."
|
|
271
|
+
] }) : "Nahrát" })
|
|
272
|
+
] })
|
|
273
|
+
] })
|
|
166
274
|
}
|
|
167
275
|
)
|
|
168
276
|
] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileInputForm.js","sources":["../../../lib/components/form/FileInputForm.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback } from \"react\";\r\nimport { useDropzone } from \"react-dropzone\";\r\nimport { MdDeleteOutline, MdInsertDriveFile } from \"react-icons/md\";\r\nimport { AxiosError } from \"axios\";\r\nimport { cn } from \"../../utils/utils\";\r\nimport { IAttachment } from \"../../types\";\r\nimport { handleErrors, useFederationContext, useFormField } from \"../../main\";\r\n\r\nexport interface FileInputFormProps {\r\n name: string;\r\n value?: IAttachment | null;\r\n onFileChanged: (file: IAttachment | null) => void;\r\n description?: string;\r\n disabled?: boolean;\r\n attachmentName?: string;\r\n attachmentType?: string;\r\n}\r\n\r\nconst MAX_FILE_SIZE = 1024 * 1024; // 1MB\r\n\r\nconst FileInputForm: React.FC<FileInputFormProps> = ({\r\n value,\r\n onFileChanged,\r\n name,\r\n description,\r\n disabled,\r\n attachmentName,\r\n attachmentType,\r\n}) => {\r\n const [fileData, setFileData] = useState<IAttachment | null>(value || null);\r\n const [isFocused, setIsFocused] = useState(false);\r\n\r\n const federationContext = useFederationContext();\r\n const { error } = useFormField();\r\n const hasError = !!error;\r\n useEffect(() => {\r\n setFileData(value || null);\r\n }, [value]);\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<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 const uploadedFile = response.data;\r\n setFileData(uploadedFile);\r\n onFileChanged(uploadedFile);\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 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(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 <div\r\n className={cn(\r\n `self-stretch px-2 py-2 rounded-lg justify-start items-center gap-2 inline-flex outline-none border`,\r\n isFocused &&\r\n !hasError &&\r\n \"outline-4 outline-indigo-200 outline-offset-0 border-indigo-300\",\r\n\r\n hasError &&\r\n \"outline-4 outline-red-200 outline-offset-0 border-none\",\r\n !isFocused && hasError && \"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 </div>\r\n );\r\n};\r\n\r\nexport default FileInputForm;\r\n"],"names":["error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FileInputForm.js","sources":["../../../lib/components/form/FileInputForm.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback } from \"react\";\r\nimport { useDropzone } from \"react-dropzone\";\r\nimport { MdDeleteOutline, MdInsertDriveFile } from \"react-icons/md\";\r\nimport { AxiosError } from \"axios\";\r\nimport { LoaderCircleIcon } from \"lucide-react\";\r\nimport { cn } from \"../../utils/utils\";\r\nimport { IAttachment } from \"../../types\";\r\nimport { handleErrors, useFederationContext, useFormField } from \"../../main\";\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from \"../ui/Dialog\";\r\nimport { Input } from \"../ui/input\";\r\nimport { Button } from \"../ui/button\";\r\n\r\nexport interface FileInputFormProps {\r\n name: string;\r\n value?: IAttachment | null;\r\n onFileChanged: (file: IAttachment | null) => void;\r\n description?: string;\r\n disabled?: boolean;\r\n attachmentName?: string;\r\n attachmentType?: string;\r\n askForAttachmentName?: boolean;\r\n}\r\n\r\nconst MAX_FILE_SIZE = 1024 * 1024; // 1MB\r\n\r\nconst FileInputForm: React.FC<FileInputFormProps> = ({\r\n value,\r\n onFileChanged,\r\n name,\r\n description,\r\n disabled,\r\n attachmentName,\r\n attachmentType,\r\n askForAttachmentName = false,\r\n}) => {\r\n const [fileData, setFileData] = useState<IAttachment | null>(value || null);\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [pendingFile, setPendingFile] = useState<File | null>(null);\r\n const [isDialogOpen, setIsDialogOpen] = useState(false);\r\n const [fileName, setFileName] = useState<string>(\"\");\r\n const [isUploading, setIsUploading] = useState(false);\r\n\r\n const federationContext = useFederationContext();\r\n const { error } = useFormField();\r\n const hasError = !!error;\r\n useEffect(() => {\r\n setFileData(value || null);\r\n }, [value]);\r\n const uploadFile = useCallback(\r\n async (file: File, customName?: string) => {\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 setIsUploading(true);\r\n const formData = new FormData();\r\n\r\n // Add the JSON data object\r\n const dataObject = {\r\n ...(customName\r\n ? { attachmentName: customName }\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<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 const uploadedFile = response.data;\r\n setFileData(uploadedFile);\r\n onFileChanged(uploadedFile);\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 } finally {\r\n setIsUploading(false);\r\n }\r\n },\r\n [\r\n federationContext.apiClient,\r\n federationContext.emitter,\r\n onFileChanged,\r\n attachmentName,\r\n attachmentType,\r\n ]\r\n );\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 if (askForAttachmentName) {\r\n setPendingFile(file);\r\n setFileName(file.name);\r\n setIsDialogOpen(true);\r\n } else {\r\n await uploadFile(file);\r\n }\r\n }\r\n },\r\n [askForAttachmentName, uploadFile, federationContext]\r\n );\r\n\r\n const handleDialogSubmit = async () => {\r\n if (pendingFile) {\r\n setIsDialogOpen(false);\r\n await uploadFile(pendingFile, fileName);\r\n setPendingFile(null);\r\n setFileName(\"\");\r\n }\r\n };\r\n\r\n const handleDialogCancel = () => {\r\n setIsDialogOpen(false);\r\n setPendingFile(null);\r\n setFileName(\"\");\r\n };\r\n\r\n const formatFileSize = (bytes: number): string => {\r\n if (bytes === 0) return \"0 Bytes\";\r\n const k = 1024;\r\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return Math.round(bytes / Math.pow(k, i) * 100) / 100 + \" \" + sizes[i];\r\n };\r\n\r\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\r\n onDrop,\r\n disabled: disabled || isUploading,\r\n multiple: false,\r\n });\r\n\r\n const handleRemove = () => {\r\n setFileData(null);\r\n onFileChanged(null);\r\n };\r\n\r\n return (\r\n <>\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 <div\r\n className={cn(\r\n `self-stretch px-2 py-2 rounded-lg justify-start items-center gap-2 inline-flex outline-none border relative`,\r\n isFocused &&\r\n !hasError &&\r\n \"outline-4 outline-indigo-200 outline-offset-0 border-indigo-300\",\r\n\r\n hasError &&\r\n \"outline-4 outline-red-200 outline-offset-0 border-none\",\r\n !isFocused && hasError && \"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 {isUploading && (\r\n <div className=\"absolute inset-0 bg-white/80 backdrop-blur-sm rounded-lg z-10 flex items-center justify-center\">\r\n <div className=\"flex flex-col items-center gap-2\">\r\n <LoaderCircleIcon className=\"h-8 w-8 animate-spin text-primary\" />\r\n <p className=\"text-sm text-gray-600\">Nahrávání...</p>\r\n </div>\r\n </div>\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={cn(\r\n `w-full p-4 border-dashed border-2 rounded-lg text-center`,\r\n isUploading\r\n ? \"cursor-not-allowed opacity-50\"\r\n : \"cursor-pointer hover:bg-gray-100\",\r\n isDragActive ? \"border-indigo-300 bg-indigo-50\" : \"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 py-2 border-b\">\r\n <div className=\"flex flex-col flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <MdInsertDriveFile style={{ fontSize: \"2rem\" }} />\r\n <div className=\"flex flex-col flex-1\">\r\n <a\r\n href={`/api/files/download/${fileData.id}`}\r\n className=\"text-left underline text-primary text-sm cursor-pointer\"\r\n target=\"_blank\"\r\n >\r\n {fileData.filename}\r\n </a>\r\n {fileData.attachmentName && (\r\n <div className=\"text-sm text-gray-600\">\r\n {fileData.attachmentName}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n {!disabled && !isUploading && (\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 </div>\r\n\r\n <Dialog\r\n open={isDialogOpen}\r\n onOpenChange={(open) => {\r\n setIsDialogOpen(open);\r\n if (!open) {\r\n handleDialogCancel();\r\n }\r\n }}\r\n >\r\n <DialogContent className=\"max-w-lg\">\r\n <DialogHeader>\r\n <DialogTitle>Zadejte popis přílohy</DialogTitle>\r\n </DialogHeader>\r\n {pendingFile && (\r\n <div className=\"space-y-4 py-4\">\r\n <div className=\"flex flex-col gap-2 p-4 border rounded-lg\">\r\n <div className=\"flex items-center gap-2\">\r\n <MdInsertDriveFile style={{ fontSize: \"1.5rem\" }} />\r\n <div className=\"flex-1\">\r\n <div className=\"font-medium text-sm\">{pendingFile.name}</div>\r\n <div className=\"text-xs text-gray-500\">\r\n {formatFileSize(pendingFile.size)}\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"mt-2\">\r\n <label className=\"text-sm font-medium mb-1 block\">\r\n Popis přílohy:\r\n </label>\r\n <Input\r\n value={fileName}\r\n onChange={(e) => setFileName(e.target.value)}\r\n placeholder=\"Zadejte popis přílohy\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n <DialogFooter>\r\n <Button variant=\"outline\" onClick={handleDialogCancel} disabled={isUploading}>\r\n Zrušit\r\n </Button>\r\n <Button onClick={handleDialogSubmit} disabled={isUploading}>\r\n {isUploading ? (\r\n <>\r\n <LoaderCircleIcon className=\"h-4 w-4 animate-spin mr-2\" />\r\n Nahrávání...\r\n </>\r\n ) : (\r\n \"Nahrát\"\r\n )}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n </>\r\n );\r\n};\r\n\r\nexport default FileInputForm;\r\n"],"names":["error","LoaderCircleIcon"],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ interface FileInputFormMultipleProps {
|
|
|
11
11
|
initialFileIds?: number[];
|
|
12
12
|
attachmentName?: string;
|
|
13
13
|
attachmentType?: string;
|
|
14
|
+
askForAttachmentName?: boolean;
|
|
14
15
|
}
|
|
15
16
|
declare const FileInputFormMultiple: React.FC<FileInputFormMultipleProps>;
|
|
16
17
|
export default FileInputFormMultiple;
|