albinasoft-ui-package 1.1.52 → 1.1.54
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.
@@ -20,6 +20,7 @@ export interface FileUploaderTranslations {
|
|
20
20
|
fileSizeError: string;
|
21
21
|
fileTypeError: string;
|
22
22
|
noFileSelectedWarning: string;
|
23
|
+
pendingBeforeSubmitWarning?: string;
|
23
24
|
}
|
24
25
|
export declare const defaultTranslations: FileUploaderTranslations;
|
25
26
|
export interface CustomFileUploaderProps {
|
@@ -61,5 +62,9 @@ export interface CustomFileUploaderProps {
|
|
61
62
|
*/
|
62
63
|
onUploadingChange?: (uploading: boolean) => void;
|
63
64
|
}
|
64
|
-
|
65
|
+
export type CustomFileUploaderHandle = {
|
66
|
+
/** Pending dosya varsa toast gösterir ve false döner. */
|
67
|
+
validateReady: () => boolean;
|
68
|
+
};
|
69
|
+
declare const CustomFileUploader: React.ForwardRefExoticComponent<CustomFileUploaderProps & React.RefAttributes<CustomFileUploaderHandle>>;
|
65
70
|
export default CustomFileUploader;
|
@@ -112,7 +112,8 @@ exports.defaultTranslations = {
|
|
112
112
|
uploadWarningExceed: "Seçilen dosya sayısı limiti aştı. Eklenebilecek dosya sayısı: ",
|
113
113
|
fileSizeError: "isimli dosya, boyut limitini aşıyor.",
|
114
114
|
fileTypeError: "isimli dosya, seçilen dosya türüne uygun değil.",
|
115
|
-
noFileSelectedWarning: "Önce en az bir dosya seçiniz."
|
115
|
+
noFileSelectedWarning: "Önce en az bir dosya seçiniz.",
|
116
|
+
pendingBeforeSubmitWarning: "Henüz yüklenmemiş dosyalar var. Lütfen önce 'Yükle' butonuna basın."
|
116
117
|
};
|
117
118
|
// ====================
|
118
119
|
// Stil Ayarları
|
@@ -221,12 +222,23 @@ var isAllowedFileType = function (file, allowedType) {
|
|
221
222
|
// ====================
|
222
223
|
// CustomFileUploader Bileşeni
|
223
224
|
// ====================
|
224
|
-
var CustomFileUploader = function (props) {
|
225
|
+
var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
|
225
226
|
var url = props.url, multi = props.multi, allowedTypes = props.allowedTypes, maxFile = props.maxFile, maxSize = props.maxSize, onUploadComplete = props.onUploadComplete, onRemoveUploaded = props.onRemoveUploaded, label = props.label, onPendingChange = props.onPendingChange, translations = props.translations, clearTrigger = props.clearTrigger, onUploadingChange = props.onUploadingChange;
|
226
227
|
// Varsayılan çeviri metinlerini, gelen prop ile birleştiriyoruz.
|
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
|
+
// Parent submit öncesi çağırıyor: pending varsa uyar ve blokla
|
232
|
+
(0, react_1.useImperativeHandle)(ref, function () { return ({
|
233
|
+
validateReady: function () {
|
234
|
+
var hasPending = previews.some(function (p) { return !p.uploaded; });
|
235
|
+
if (hasPending) {
|
236
|
+
react_toastify_1.toast.warning(finalTranslations.pendingBeforeSubmitWarning || exports.defaultTranslations.pendingBeforeSubmitWarning);
|
237
|
+
return false;
|
238
|
+
}
|
239
|
+
return true;
|
240
|
+
}
|
241
|
+
}); }, [previews, finalTranslations]);
|
230
242
|
// CustomFileUploader.tsx içinde component’in üst kısmına, diğer handler’ların yanına ekleyin:
|
231
243
|
var handleClearAll = function () {
|
232
244
|
previews.forEach(function (item) {
|
@@ -456,5 +468,5 @@ var CustomFileUploader = function (props) {
|
|
456
468
|
react_1.default.createElement("div", { className: "d-flex justify-content-center gap-2 mt-3" },
|
457
469
|
previews.length > 1 && (react_1.default.createElement(CustomButton_1.default, { label: "T\u00FCm\u00FCn\u00FC Sil", className: "btn btn-danger", onClick: handleClearAll })),
|
458
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 })))));
|
459
|
-
};
|
471
|
+
});
|
460
472
|
exports.default = CustomFileUploader;
|
@@ -219,6 +219,7 @@ interface CustomFormProps {
|
|
219
219
|
handleCancel?: () => void;
|
220
220
|
showConfirmButton?: boolean;
|
221
221
|
showCancelButton?: boolean;
|
222
|
+
fileUploaderCheck?: () => boolean;
|
222
223
|
}
|
223
224
|
declare const CustomForm: React.FC<CustomFormProps>;
|
224
225
|
export { CustomForm, ElementType };
|
@@ -117,18 +117,36 @@ var CustomForm = function (_a) {
|
|
117
117
|
cancelLabel = _c === void 0 ? "Cancel" : _c, // Varsayılan değer
|
118
118
|
handleCancel = _a.handleCancel, _d = _a.showConfirmButton, showConfirmButton = _d === void 0 ? true : _d, // Varsayılan olarak görünür
|
119
119
|
_e = _a.showCancelButton, // Varsayılan olarak görünür
|
120
|
-
showCancelButton = _e === void 0 ? false : _e
|
120
|
+
showCancelButton = _e === void 0 ? false : _e, // Varsayılan olarak görünür
|
121
|
+
fileUploaderCheck = _a.fileUploaderCheck;
|
121
122
|
var formRef = (0, react_1.useRef)(null);
|
122
123
|
var _f = (0, react_1.useState)(false), isLoading = _f[0], setIsLoading = _f[1];
|
123
124
|
var _g = (0, react_1.useState)(false), submitted = _g[0], setSubmitted = _g[1];
|
124
125
|
var _h = (0, react_1.useState)(false), isUploading = _h[0], setIsUploading = _h[1];
|
126
|
+
// Her uploader için ref havuzu
|
127
|
+
var uploaderInstances = (0, react_1.useRef)({});
|
128
|
+
// Bir kez oluştur: id -> ref
|
129
|
+
var getUploaderRefCb = function (id) { return function (inst) {
|
130
|
+
uploaderInstances.current[id] = inst;
|
131
|
+
}; };
|
125
132
|
var handleConfirm = function (e) { return __awaiter(void 0, void 0, void 0, function () {
|
126
|
-
var form, customSelectValid, customTreeViewValid, isValid, formValues_1, error_1;
|
127
|
-
|
128
|
-
|
133
|
+
var instances, _i, instances_1, inst, ok, form, customSelectValid, customTreeViewValid, isValid, formValues_1, error_1;
|
134
|
+
var _a;
|
135
|
+
return __generator(this, function (_b) {
|
136
|
+
switch (_b.label) {
|
129
137
|
case 0:
|
130
138
|
e.preventDefault();
|
131
139
|
setSubmitted(true); // Form gönderimi tetiklendi
|
140
|
+
instances = Object.values(uploaderInstances.current);
|
141
|
+
for (_i = 0, instances_1 = instances; _i < instances_1.length; _i++) {
|
142
|
+
inst = instances_1[_i];
|
143
|
+
ok = (_a = inst === null || inst === void 0 ? void 0 : inst.validateReady) === null || _a === void 0 ? void 0 : _a.call(inst);
|
144
|
+
if (ok === false) {
|
145
|
+
// Uyarıyı uploader kendisi gösterdi; submit başlamasın.
|
146
|
+
return [2 /*return*/];
|
147
|
+
}
|
148
|
+
}
|
149
|
+
setSubmitted(true);
|
132
150
|
form = formRef.current;
|
133
151
|
if (!form)
|
134
152
|
return [2 /*return*/];
|
@@ -158,9 +176,9 @@ var CustomForm = function (_a) {
|
|
158
176
|
isValid = form.checkValidity() && customSelectValid && customTreeViewValid;
|
159
177
|
if (!isValid) return [3 /*break*/, 6];
|
160
178
|
setIsLoading(true);
|
161
|
-
|
179
|
+
_b.label = 1;
|
162
180
|
case 1:
|
163
|
-
|
181
|
+
_b.trys.push([1, 3, 4, 5]);
|
164
182
|
formValues_1 = {};
|
165
183
|
Array.from(form.elements).forEach(function (element) {
|
166
184
|
if (element instanceof HTMLInputElement ||
|
@@ -200,10 +218,10 @@ var CustomForm = function (_a) {
|
|
200
218
|
});
|
201
219
|
return [4 /*yield*/, onSubmit(formValues_1)];
|
202
220
|
case 2:
|
203
|
-
|
221
|
+
_b.sent();
|
204
222
|
return [3 /*break*/, 5];
|
205
223
|
case 3:
|
206
|
-
error_1 =
|
224
|
+
error_1 = _b.sent();
|
207
225
|
react_toastify_1.toast.error("Form gönderimi sırasında bir hata oluştu.");
|
208
226
|
return [3 /*break*/, 5];
|
209
227
|
case 4:
|
@@ -213,7 +231,7 @@ var CustomForm = function (_a) {
|
|
213
231
|
case 6:
|
214
232
|
react_toastify_1.toast.error("Gerekli tüm alanları doldurunuz.");
|
215
233
|
form.classList.add("was-validated");
|
216
|
-
|
234
|
+
_b.label = 7;
|
217
235
|
case 7: return [2 /*return*/];
|
218
236
|
}
|
219
237
|
});
|
@@ -246,7 +264,7 @@ var CustomForm = function (_a) {
|
|
246
264
|
} }))) : 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 ? (
|
247
265
|
// FILEUPLOADER elemanı için CustomFileUploader'ı render ediyoruz
|
248
266
|
react_1.default.createElement(react_1.default.Fragment, null,
|
249
|
-
react_1.default.createElement(CustomFileUploader_1.default, { 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 }))) : null)); })));
|
267
|
+
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 }))) : null)); })));
|
250
268
|
})));
|
251
269
|
})));
|
252
270
|
}),
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "albinasoft-ui-package",
|
3
|
-
"version": "1.1.
|
3
|
+
"version": "1.1.54",
|
4
4
|
"main": "dist/index.js",
|
5
5
|
"types": "dist/index.d.ts",
|
6
6
|
"scripts": {
|
@@ -15,17 +15,17 @@
|
|
15
15
|
"date-fns": "^4.1.0",
|
16
16
|
"date-fns-tz": "^3.2.0",
|
17
17
|
"quill": "^2.0.3",
|
18
|
-
"react": "^18.0.0",
|
19
18
|
"react-bootstrap": "^2.10.6",
|
20
19
|
"react-checkbox-tree": "^1.8.0",
|
21
20
|
"react-datepicker": "^7.6.0",
|
22
|
-
"react-dom": "^18.0.0",
|
23
21
|
"react-icons": "^4.12.0",
|
24
22
|
"react-input-mask": "^2.0.4",
|
25
|
-
"react-router-dom": "^7.1.1"
|
26
|
-
"react-toastify": "^10.0.6"
|
23
|
+
"react-router-dom": "^7.1.1"
|
27
24
|
},
|
28
25
|
"devDependencies": {
|
26
|
+
"react": "^18.0.0",
|
27
|
+
"react-dom": "^18.0.0",
|
28
|
+
"react-toastify": "^10.0.6",
|
29
29
|
"@types/react": "^19.0.1",
|
30
30
|
"@types/react-bootstrap": "^0.32.37",
|
31
31
|
"@types/react-input-mask": "^3.0.6",
|
@@ -34,7 +34,8 @@
|
|
34
34
|
},
|
35
35
|
"peerDependencies": {
|
36
36
|
"react": "^18.0.0",
|
37
|
-
"react-dom": "^18.0.0"
|
37
|
+
"react-dom": "^18.0.0",
|
38
|
+
"react-toastify": "^10.0.0"
|
38
39
|
},
|
39
40
|
"files": [
|
40
41
|
"dist"
|