albinasoft-ui-package 1.1.60 → 1.1.61
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.
@@ -22,6 +22,7 @@ export interface FileUploaderTranslations {
|
|
22
22
|
fileTypeError: string;
|
23
23
|
noFileSelectedWarning: string;
|
24
24
|
pendingBeforeSubmitWarning?: string;
|
25
|
+
requiredBeforeSubmitWarning?: string;
|
25
26
|
}
|
26
27
|
export declare const defaultTranslations: FileUploaderTranslations;
|
27
28
|
export interface CustomFileUploaderProps {
|
@@ -35,6 +36,8 @@ export interface CustomFileUploaderProps {
|
|
35
36
|
maxFile: number;
|
36
37
|
/** Her bir dosya için maksimum boyut (byte cinsinden) */
|
37
38
|
maxSize: number;
|
39
|
+
required?: boolean;
|
40
|
+
submitted?: boolean;
|
38
41
|
/**
|
39
42
|
* Opsiyonel: Yükleme tamamlandığında dönen dosya isimlerini almak için callback.
|
40
43
|
*/
|
@@ -112,7 +112,8 @@ exports.defaultTranslations = {
|
|
112
112
|
fileSizeError: "isimli dosya, boyut limitini aşıyor.",
|
113
113
|
fileTypeError: "isimli dosya, seçilen dosya türüne uygun değil.",
|
114
114
|
noFileSelectedWarning: "Önce en az bir dosya seçiniz.",
|
115
|
-
pendingBeforeSubmitWarning: "Henüz yüklenmemiş dosyalar var. Lütfen önce 'Yükle' butonuna basın."
|
115
|
+
pendingBeforeSubmitWarning: "Henüz yüklenmemiş dosyalar var. Lütfen önce 'Yükle' butonuna basın.",
|
116
|
+
requiredBeforeSubmitWarning: "En az bir dosya yüklemiş olmalısınız."
|
116
117
|
};
|
117
118
|
// ====================
|
118
119
|
// Stil Ayarları
|
@@ -130,7 +131,7 @@ var spinnerStyle = {
|
|
130
131
|
zIndex: 3,
|
131
132
|
};
|
132
133
|
var dropAreaStyle = {
|
133
|
-
border: "2px dashed #007bff",
|
134
|
+
//border: "2px dashed #007bff",
|
134
135
|
borderRadius: "5px",
|
135
136
|
padding: "20px",
|
136
137
|
textAlign: "center",
|
@@ -227,6 +228,7 @@ var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
|
|
227
228
|
var finalTranslations = __assign(__assign({}, exports.defaultTranslations), translations);
|
228
229
|
var _a = (0, react_1.useState)([]), previews = _a[0], setPreviews = _a[1];
|
229
230
|
var fileInputRef = (0, react_1.useRef)(null);
|
231
|
+
var isInvalid = props.required && props.submitted && !previews.some(function (p) { return p.uploaded; });
|
230
232
|
// Parent submit öncesi çağırıyor: pending varsa uyar ve blokla
|
231
233
|
(0, react_1.useImperativeHandle)(ref, function () { return ({
|
232
234
|
validateReady: function () {
|
@@ -235,9 +237,17 @@ var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
|
|
235
237
|
onNotify === null || onNotify === void 0 ? void 0 : onNotify.warning(finalTranslations.pendingBeforeSubmitWarning || exports.defaultTranslations.pendingBeforeSubmitWarning);
|
236
238
|
return false;
|
237
239
|
}
|
240
|
+
// REQUIRED kuralı: en az 1 adet YÜKLENMİŞ dosya olmalı
|
241
|
+
if (props.required) {
|
242
|
+
var hasUploaded = previews.some(function (p) { return p.uploaded; });
|
243
|
+
if (!hasUploaded) {
|
244
|
+
onNotify === null || onNotify === void 0 ? void 0 : onNotify.warning(finalTranslations.requiredBeforeSubmitWarning || exports.defaultTranslations.requiredBeforeSubmitWarning);
|
245
|
+
return false;
|
246
|
+
}
|
247
|
+
}
|
238
248
|
return true;
|
239
249
|
}
|
240
|
-
}); }, [previews, finalTranslations, onNotify]);
|
250
|
+
}); }, [previews, finalTranslations, onNotify, props.required]);
|
241
251
|
// CustomFileUploader.tsx içinde component’in üst kısmına, diğer handler’ların yanına ekleyin:
|
242
252
|
var handleClearAll = function () {
|
243
253
|
previews.forEach(function (item) {
|
@@ -433,7 +443,7 @@ var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
|
|
433
443
|
return (react_1.default.createElement("div", { style: { width: "100%", height: "100%" } },
|
434
444
|
label && (react_1.default.createElement("div", { style: { marginBottom: "10px" } },
|
435
445
|
react_1.default.createElement("label", { style: { fontWeight: "bold" } }, label))),
|
436
|
-
react_1.default.createElement("div", { style: dropAreaStyle, onDrop: handleDrop, onDragOver: handleDragOver, onClick: handleAreaClick }, previews.length === 0 ? (react_1.default.createElement("div", null, dropAreaText)) : (react_1.default.createElement("div", { style: previewContainerStyle }, previews.map(function (item) { return (react_1.default.createElement("div", { key: item.id, style: { display: "flex", flexDirection: "column", alignItems: "center" } },
|
446
|
+
react_1.default.createElement("div", { style: __assign(__assign({}, dropAreaStyle), { border: isInvalid ? "2px dashed #ff0000ff" : "2px dashed #007bff" }), onDrop: handleDrop, onDragOver: handleDragOver, onClick: handleAreaClick }, previews.length === 0 ? (react_1.default.createElement("div", null, dropAreaText)) : (react_1.default.createElement("div", { style: previewContainerStyle }, previews.map(function (item) { return (react_1.default.createElement("div", { key: item.id, style: { display: "flex", flexDirection: "column", alignItems: "center" } },
|
437
447
|
react_1.default.createElement("div", { style: previewItemStyle },
|
438
448
|
item.isUploading && react_1.default.createElement("div", { style: spinnerStyle }),
|
439
449
|
item.isImage ? (react_1.default.createElement("img", { src: item.previewContent, alt: "\u00D6nizleme ".concat(item.id), style: {
|
@@ -467,6 +477,9 @@ var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
|
|
467
477
|
react_1.default.createElement("input", { type: "file", multiple: multi, ref: fileInputRef, onChange: handleFileChange, style: { display: "none" } }),
|
468
478
|
react_1.default.createElement("div", { className: "d-flex justify-content-center gap-2 mt-3" },
|
469
479
|
previews.length > 1 && (react_1.default.createElement(CustomButton_1.default, { label: "T\u00FCm\u00FCn\u00FC Sil", className: "btn btn-danger", onClick: handleClearAll })),
|
470
|
-
previews.filter(function (item) { return !item.uploaded; }).length > 0 && (react_1.default.createElement(CustomButton_1.default, { label: finalTranslations.uploadButtonText, className: "btn btn-primary", onClick: handleUpload })))
|
480
|
+
previews.filter(function (item) { return !item.uploaded; }).length > 0 && (react_1.default.createElement(CustomButton_1.default, { label: finalTranslations.uploadButtonText, className: "btn btn-primary", onClick: handleUpload }))),
|
481
|
+
isInvalid && (react_1.default.createElement("div", { className: "invalid-feedback d-block text-danger mt-1" },
|
482
|
+
react_1.default.createElement(fa_1.FaExclamationTriangle, { className: "me-1" }),
|
483
|
+
finalTranslations.requiredBeforeSubmitWarning || "Bu alan boş bırakılamaz."))));
|
471
484
|
});
|
472
485
|
exports.default = CustomFileUploader;
|
@@ -200,6 +200,7 @@ interface FileUploaderElement {
|
|
200
200
|
allowedTypes: AllowedTypes;
|
201
201
|
maxFile: number;
|
202
202
|
maxSize: number;
|
203
|
+
required?: boolean;
|
203
204
|
onUploadComplete: (uploadedFileNames: string[]) => void;
|
204
205
|
onRemoveUploaded: (fileName: string) => void;
|
205
206
|
onPendingChange: (pendingFileCount: number) => void;
|
@@ -265,7 +265,7 @@ var CustomForm = function (_a) {
|
|
265
265
|
} }))) : element.type === ElementType.DATETIMEPICKER ? (react_1.default.createElement(CustomDateTimePicker_1.default, __assign({}, element, { submitted: submitted }))) : element.type === ElementType.DIVIDER ? (react_1.default.createElement(CustomDivider_1.default, __assign({}, element))) : element.type === ElementType.RICHTEXTBOX ? (react_1.default.createElement(CustomRichTextbox_1.default, __assign({}, element))) : element.type === ElementType.TREEVIEW ? (react_1.default.createElement(CustomTreeView_1.default, __assign({}, element, { submitted: submitted }))) : element.type === ElementType.BUTTON ? (react_1.default.createElement(CustomButton_1.default, __assign({}, element, { isLoading: isLoading }))) : element.type === ElementType.AUTOCOMPLETEINPUT ? (react_1.default.createElement(CustomAutocompleteInput_1.default, __assign({}, element))) : element.type === ElementType.PHONE ? (react_1.default.createElement(CustomPhoneInput_1.default, __assign({}, element))) : element.type === ElementType.FILEUPLOADER ? (
|
266
266
|
// FILEUPLOADER elemanı için CustomFileUploader'ı render ediyoruz
|
267
267
|
react_1.default.createElement(react_1.default.Fragment, null,
|
268
|
-
react_1.default.createElement(CustomFileUploader_1.default, { ref: getUploaderRefCb(element.id), url: element.url, multi: element.multi, allowedTypes: element.allowedTypes, maxFile: element.maxFile, maxSize: element.maxSize, onUploadComplete: element.onUploadComplete, onRemoveUploaded: element.onRemoveUploaded, onPendingChange: element.onPendingChange, clearTrigger: element.clearTrigger, label: element.label, translations: element.translations, onUploadingChange: setIsUploading, onNotify: onNotify }))) : null)); })));
|
268
|
+
react_1.default.createElement(CustomFileUploader_1.default, { ref: getUploaderRefCb(element.id), url: element.url, multi: element.multi, allowedTypes: element.allowedTypes, maxFile: element.maxFile, maxSize: element.maxSize, required: element.required, submitted: submitted, onUploadComplete: element.onUploadComplete, onRemoveUploaded: element.onRemoveUploaded, onPendingChange: element.onPendingChange, clearTrigger: element.clearTrigger, label: element.label, translations: element.translations, onUploadingChange: setIsUploading, onNotify: onNotify }))) : null)); })));
|
269
269
|
})));
|
270
270
|
})));
|
271
271
|
}),
|