@pnkx-lib/ui 1.9.352 → 1.9.354
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/es/fields/Input.js
CHANGED
|
@@ -1433,6 +1433,7 @@ const NumericFormatCustom = forwardRef((props, ref) => {
|
|
|
1433
1433
|
} = props;
|
|
1434
1434
|
const isMoney = type === "money";
|
|
1435
1435
|
const isNumberCustom = type === "number_custom";
|
|
1436
|
+
const MAX_VALUE = 999999999999999;
|
|
1436
1437
|
//! Function
|
|
1437
1438
|
const handleValueChange = (values) => {
|
|
1438
1439
|
const numericValue = parseFloat(values.value.replace(/,/g, ""));
|
|
@@ -1457,11 +1458,15 @@ const NumericFormatCustom = forwardRef((props, ref) => {
|
|
|
1457
1458
|
customInput: Input,
|
|
1458
1459
|
onValueChange: handleValueChange,
|
|
1459
1460
|
value,
|
|
1460
|
-
thousandSeparator: isNumberCustom ?
|
|
1461
|
-
decimalSeparator: isNumberCustom ?
|
|
1461
|
+
thousandSeparator: isNumberCustom ? `,` : ".",
|
|
1462
|
+
decimalSeparator: isNumberCustom ? `.` : ",",
|
|
1462
1463
|
valueIsNumericString: true,
|
|
1463
1464
|
getInputRef: ref,
|
|
1464
1465
|
prefix: isMoney ? "$" : prefix,
|
|
1466
|
+
isAllowed: (values) => {
|
|
1467
|
+
const { floatValue } = values;
|
|
1468
|
+
return floatValue === void 0 || floatValue <= MAX_VALUE;
|
|
1469
|
+
},
|
|
1465
1470
|
...restProps
|
|
1466
1471
|
}
|
|
1467
1472
|
),
|
package/es/fields/Select.js
CHANGED
|
@@ -6,6 +6,7 @@ import { Label } from '../ui/Label.js';
|
|
|
6
6
|
import { t as twMerge } from '../chunks/bundle-mjs-BBFHkixS.js';
|
|
7
7
|
import { R as RefIcon } from '../chunks/CloseOutlined-D4eYNdNo.js';
|
|
8
8
|
import { R as RefIcon$1 } from '../chunks/DownOutlined-DifOcKuo.js';
|
|
9
|
+
import { useRef } from 'react';
|
|
9
10
|
import { M as MAX_TAG_TEXT_LENGTH, a as MAX_TAG_COUNT } from '../chunks/common-BcURBmQ-.js';
|
|
10
11
|
|
|
11
12
|
const SelectClearIcon = ({
|
|
@@ -78,10 +79,14 @@ const Select = (props) => {
|
|
|
78
79
|
const { touchedFields, errors, isSubmitted } = formState || {};
|
|
79
80
|
const isTouched = get(touchedFields, name);
|
|
80
81
|
const errorMessage = get(errors, name)?.message;
|
|
82
|
+
const selectRef = useRef(null);
|
|
81
83
|
//! Function
|
|
82
84
|
const handleChange = (val) => {
|
|
83
85
|
onChange?.(val);
|
|
84
86
|
afterOnChange?.(val);
|
|
87
|
+
if (mode === "multiple" && selectRef.current) {
|
|
88
|
+
selectRef.current?.focus();
|
|
89
|
+
}
|
|
85
90
|
};
|
|
86
91
|
const renderErrorMessage = () => {
|
|
87
92
|
if (!errorMessage) return null;
|
|
@@ -123,6 +128,7 @@ const Select = (props) => {
|
|
|
123
128
|
/* @__PURE__ */ jsx(
|
|
124
129
|
Select$1,
|
|
125
130
|
{
|
|
131
|
+
ref: selectRef,
|
|
126
132
|
suffixIcon,
|
|
127
133
|
onChange: handleChange,
|
|
128
134
|
onBlur,
|
package/es/ui/ImportFile.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { Upload } from 'antd';
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import { useState } from 'react';
|
|
5
3
|
import { R as RefIcon$2 } from '../chunks/InboxOutlined-DNCJCjk3.js';
|
|
6
4
|
import { I as Icon, _ as _extends } from '../chunks/AntdIcon-DSoxq9aC.js';
|
|
5
|
+
import * as React from 'react';
|
|
7
6
|
|
|
8
7
|
// This icon file is generated automatically.
|
|
9
8
|
var CheckCircleFilled$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z" } }] }, "name": "check-circle", "theme": "filled" };
|
|
@@ -38,74 +37,25 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
const { Dragger } = Upload;
|
|
41
|
-
const ImportFile = ({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const { file, onSuccess, onError } = options;
|
|
49
|
-
const maxSize = 5 * 1024 * 1024;
|
|
50
|
-
if (file.size > maxSize) {
|
|
51
|
-
setStatus((prev) => ({
|
|
52
|
-
...prev,
|
|
53
|
-
type: "error",
|
|
54
|
-
message: `File ${file.name} có kích thước quá lớn.
|
|
55
|
-
|
|
56
|
-
${file.name} không đúng định dạng! Vui lòng tải lại file này, xem các lỗi được ghi chú, sau đó chỉnh sửa và thử nhập lại.
|
|
57
|
-
|
|
58
|
-
Việc tải lên không thể hoàn tất do kết nối mạng hiện tại bị gián đoạn hoặc quá chậm.`
|
|
59
|
-
}));
|
|
60
|
-
onError(new Error("File too large"));
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
const formData = new FormData();
|
|
64
|
-
formData.append("file", file);
|
|
65
|
-
formData.append("upload_preset", "ml_default");
|
|
66
|
-
setLoading(true);
|
|
67
|
-
try {
|
|
68
|
-
const res = await fetch(
|
|
69
|
-
"https://api.cloudinary.com/v1_1/dhtrzmzd3/auto/upload",
|
|
70
|
-
{
|
|
71
|
-
method: "POST",
|
|
72
|
-
body: formData
|
|
73
|
-
}
|
|
74
|
-
);
|
|
75
|
-
const data = await res.json();
|
|
76
|
-
setStatus((prev) => ({
|
|
77
|
-
...prev,
|
|
78
|
-
type: "success",
|
|
79
|
-
message: "File đã tải lên thành công! vui lòng ấn xác nhận để lưu dữ liệu vào database"
|
|
80
|
-
}));
|
|
81
|
-
onSuccess(data);
|
|
82
|
-
if (onUploadSuccess) {
|
|
83
|
-
onUploadSuccess(data);
|
|
84
|
-
}
|
|
85
|
-
} catch (err) {
|
|
86
|
-
console.error("Upload failed:", err);
|
|
87
|
-
onError(err);
|
|
88
|
-
setStatus((prev) => ({
|
|
89
|
-
...prev,
|
|
90
|
-
type: "error",
|
|
91
|
-
message: `Việc tải lên không thể hoàn tất do kết nối mạng hiện tại bị gián đoạn hoặc quá chậm.`
|
|
92
|
-
}));
|
|
93
|
-
} finally {
|
|
94
|
-
setLoading(false);
|
|
95
|
-
}
|
|
96
|
-
};
|
|
40
|
+
const ImportFile = ({
|
|
41
|
+
customRequest,
|
|
42
|
+
loading,
|
|
43
|
+
status,
|
|
44
|
+
setStatus,
|
|
45
|
+
...rest
|
|
46
|
+
}) => {
|
|
97
47
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
98
48
|
/* @__PURE__ */ jsx(
|
|
99
49
|
Dragger,
|
|
100
50
|
{
|
|
101
|
-
customRequest
|
|
51
|
+
customRequest,
|
|
102
52
|
listType: "picture",
|
|
103
53
|
accept: ".xlsx",
|
|
104
54
|
...rest,
|
|
105
|
-
onRemove: () => setStatus(
|
|
55
|
+
onRemove: () => setStatus({
|
|
106
56
|
message: "",
|
|
107
57
|
type: ""
|
|
108
|
-
})
|
|
58
|
+
}),
|
|
109
59
|
children: /* @__PURE__ */ jsxs("div", { children: [
|
|
110
60
|
/* @__PURE__ */ jsx("p", { className: "ant-upload-drag-icon", children: /* @__PURE__ */ jsx(RefIcon$2, {}) }),
|
|
111
61
|
/* @__PURE__ */ jsx("p", { className: "ant-upload-text", children: "Kéo tập tin của bạn hoặc nhấp để duyệt một tập tin" }),
|
|
@@ -113,9 +63,9 @@ const ImportFile = ({ onUploadSuccess, ...rest }) => {
|
|
|
113
63
|
] })
|
|
114
64
|
}
|
|
115
65
|
),
|
|
116
|
-
status
|
|
117
|
-
status
|
|
118
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm", children: status
|
|
66
|
+
status?.message && !loading && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 mt-4", children: [
|
|
67
|
+
status?.type === "error" ? /* @__PURE__ */ jsx(RefIcon, { className: "!text-[#FF4D4F] text-xl" }) : /* @__PURE__ */ jsx(RefIcon$1, { className: "!text-[#52C41A] text-xl" }),
|
|
68
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: status?.message })
|
|
119
69
|
] })
|
|
120
70
|
] });
|
|
121
71
|
};
|
package/es/ui/UploadComponent.js
CHANGED
|
@@ -20,11 +20,13 @@ const UploadComponent = ({
|
|
|
20
20
|
content = "Tải hình ảnh lên",
|
|
21
21
|
description = "Ảnh có kích thước 400x400 px và dung lượng ảnh < 1 mb",
|
|
22
22
|
customRequest,
|
|
23
|
+
setImageUpload,
|
|
23
24
|
...restProps
|
|
24
25
|
}) => {
|
|
25
|
-
const imageUrl = field?.value;
|
|
26
|
+
const imageUrl = typeof field?.value === "string" ? field.value : field?.value instanceof File ? URL.createObjectURL(field.value) : null;
|
|
26
27
|
const handleRemoveImage = () => {
|
|
27
28
|
field.onChange(null);
|
|
29
|
+
setImageUpload?.("");
|
|
28
30
|
};
|
|
29
31
|
return /* @__PURE__ */ jsxs("div", { className: customStyleContainer, children: [
|
|
30
32
|
label && /* @__PURE__ */ jsx(Label, { label, required }),
|
|
@@ -38,11 +40,10 @@ const UploadComponent = ({
|
|
|
38
40
|
customRequest: async (options) => {
|
|
39
41
|
const { file, onSuccess, onError } = options;
|
|
40
42
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
onError?.(error);
|
|
43
|
+
await customRequest?.(file, field.onChange);
|
|
44
|
+
onSuccess?.({}, file);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
onError?.(err);
|
|
46
47
|
}
|
|
47
48
|
},
|
|
48
49
|
children: /* @__PURE__ */ jsx("div", { children: loading ? /* @__PURE__ */ jsx(Spin, {}) : imageUrl || imageUpload ? /* @__PURE__ */ jsx("div", { className: customStyleUpload, children: /* @__PURE__ */ jsxs(
|
package/package.json
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { UploadProps } from 'antd';
|
|
2
|
+
type UploadStatus = {
|
|
3
|
+
type: "success" | "error" | "";
|
|
4
|
+
message: string;
|
|
5
|
+
};
|
|
2
6
|
interface ImportFileProps extends UploadProps {
|
|
3
|
-
|
|
7
|
+
customRequest?: any;
|
|
8
|
+
loading?: boolean;
|
|
9
|
+
status?: UploadStatus;
|
|
10
|
+
setStatus(status: UploadStatus): void;
|
|
4
11
|
}
|
|
5
|
-
export declare const ImportFile: ({
|
|
12
|
+
export declare const ImportFile: ({ customRequest, loading, status, setStatus, ...rest }: ImportFileProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
13
|
export {};
|