albinasoft-ui-package 1.1.36 → 1.1.38

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.
@@ -55,6 +55,11 @@ export interface CustomFileUploaderProps {
55
55
  * Eğer bu prop’un değeri değişirse uploader içini temizle
56
56
  */
57
57
  clearTrigger?: any;
58
+ /**
59
+ * Yükleme işlemi sırasında yükleme durumunu parent'a bildirmek için callback.
60
+ * Bu, yükleme işlemi başladığında ve bittiğinde çağrılabilir.
61
+ */
62
+ onUploadingChange?: (uploading: boolean) => void;
58
63
  }
59
64
  declare const CustomFileUploader: React.FC<CustomFileUploaderProps>;
60
65
  export default CustomFileUploader;
@@ -117,6 +117,18 @@ exports.defaultTranslations = {
117
117
  // ====================
118
118
  // Stil Ayarları
119
119
  // ====================
120
+ var spinnerStyle = {
121
+ position: "absolute",
122
+ top: "40%",
123
+ left: "40%",
124
+ width: "20px",
125
+ height: "20px",
126
+ border: "2px solid #007bff",
127
+ borderTop: "2px solid transparent",
128
+ borderRadius: "50%",
129
+ animation: "spin 1s linear infinite",
130
+ zIndex: 3,
131
+ };
120
132
  var dropAreaStyle = {
121
133
  border: "2px dashed #007bff",
122
134
  borderRadius: "5px",
@@ -210,7 +222,7 @@ var isAllowedFileType = function (file, allowedType) {
210
222
  // CustomFileUploader Bileşeni
211
223
  // ====================
212
224
  var CustomFileUploader = function (props) {
213
- 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;
225
+ 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;
214
226
  // Varsayılan çeviri metinlerini, gelen prop ile birleştiriyoruz.
215
227
  var finalTranslations = __assign(__assign({}, exports.defaultTranslations), translations);
216
228
  var _a = (0, react_1.useState)([]), previews = _a[0], setPreviews = _a[1];
@@ -235,6 +247,14 @@ var CustomFileUploader = function (props) {
235
247
  handleClearAll();
236
248
  }
237
249
  }, [clearTrigger]);
250
+ (0, react_1.useEffect)(function () {
251
+ var style = document.createElement("style");
252
+ style.innerHTML = "\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n ";
253
+ document.head.appendChild(style);
254
+ return function () {
255
+ document.head.removeChild(style);
256
+ };
257
+ }, []);
238
258
  // Pending dosya sayısını parent'a iletecek yardımcı fonksiyon
239
259
  var updatePendingStatus = function (previewsArray) {
240
260
  if (onPendingChange) {
@@ -322,18 +342,25 @@ var CustomFileUploader = function (props) {
322
342
  return __generator(this, function (_a) {
323
343
  switch (_a.label) {
324
344
  case 0:
345
+ onUploadingChange === null || onUploadingChange === void 0 ? void 0 : onUploadingChange(true);
325
346
  filesToUpload = previews.filter(function (item) { return !item.uploaded; }).map(function (item) { return item.file; });
326
347
  if (filesToUpload.length === 0) {
327
348
  react_toastify_1.toast.warning(finalTranslations.noFileSelectedWarning);
328
349
  return [2 /*return*/];
329
350
  }
351
+ // Yüklenmeye başlayan dosyaları işaretle
352
+ setPreviews(function (prev) {
353
+ return prev.map(function (item) {
354
+ return !item.uploaded ? __assign(__assign({}, item), { isUploading: true }) : item;
355
+ });
356
+ });
330
357
  formData = new FormData();
331
358
  filesToUpload.forEach(function (file) {
332
359
  formData.append("file", file);
333
360
  });
334
361
  _a.label = 1;
335
362
  case 1:
336
- _a.trys.push([1, 7, , 8]);
363
+ _a.trys.push([1, 7, 8, 9]);
337
364
  return [4 /*yield*/, fetch(url, {
338
365
  method: "POST",
339
366
  body: formData,
@@ -355,7 +382,7 @@ var CustomFileUploader = function (props) {
355
382
  setPreviews(function (prev) {
356
383
  var updatedPreviews = prev.map(function (item, index) {
357
384
  if (!item.uploaded) {
358
- return __assign(__assign({}, item), { uploaded: true, serverFileName: uploadedFileNames_1[index] || item.file.name });
385
+ return __assign(__assign({}, item), { uploaded: true, isUploading: false, serverFileName: uploadedFileNames_1[index] || item.file.name });
359
386
  }
360
387
  return item;
361
388
  });
@@ -374,13 +401,16 @@ var CustomFileUploader = function (props) {
374
401
  console.error("API Hatası:", errorData);
375
402
  react_toastify_1.toast.error(finalTranslations.uploadErrorToast);
376
403
  _a.label = 6;
377
- case 6: return [3 /*break*/, 8];
404
+ case 6: return [3 /*break*/, 9];
378
405
  case 7:
379
406
  error_1 = _a.sent();
380
407
  console.error("API çağrısında hata:", error_1);
381
408
  react_toastify_1.toast.error(finalTranslations.uploadErrorToast);
382
- return [3 /*break*/, 8];
383
- case 8: return [2 /*return*/];
409
+ return [3 /*break*/, 9];
410
+ case 8:
411
+ onUploadingChange === null || onUploadingChange === void 0 ? void 0 : onUploadingChange(false);
412
+ return [7 /*endfinally*/];
413
+ case 9: return [2 /*return*/];
384
414
  }
385
415
  });
386
416
  }); };
@@ -393,10 +423,12 @@ var CustomFileUploader = function (props) {
393
423
  react_1.default.createElement("label", { style: { fontWeight: "bold" } }, label))),
394
424
  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" } },
395
425
  react_1.default.createElement("div", { style: previewItemStyle },
426
+ item.isUploading && react_1.default.createElement("div", { style: spinnerStyle }),
396
427
  item.isImage ? (react_1.default.createElement("img", { src: item.previewContent, alt: "\u00D6nizleme ".concat(item.id), style: {
397
428
  width: "100%",
398
429
  height: "100%",
399
430
  objectFit: "cover",
431
+ opacity: item.isUploading ? 0.5 : 1,
400
432
  } })) : (react_1.default.createElement("div", { style: {
401
433
  width: "100%",
402
434
  height: "100%",
@@ -404,11 +436,12 @@ var CustomFileUploader = function (props) {
404
436
  justifyContent: "center",
405
437
  alignItems: "center",
406
438
  fontSize: "48px",
439
+ opacity: item.isUploading ? 0.5 : 1,
407
440
  } }, item.previewContent)),
408
441
  react_1.default.createElement("button", { type: "button", style: removeButtonStyle, onClick: function (e) {
409
442
  e.stopPropagation();
410
443
  handleRemoveFile(item.id);
411
- }, title: finalTranslations.removeButtonTitle }, "\u00D7"),
444
+ }, title: finalTranslations.removeButtonTitle, disabled: item.isUploading }, "\u00D7"),
412
445
  item.uploaded && react_1.default.createElement("div", { style: tickOverlayStyle }, "\u2713")),
413
446
  react_1.default.createElement("div", { style: {
414
447
  marginTop: "4px",
@@ -74,6 +74,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
74
74
  };
75
75
  Object.defineProperty(exports, "__esModule", { value: true });
76
76
  exports.ElementType = exports.CustomForm = void 0;
77
+ //CustomForm.tsx
77
78
  var react_1 = __importStar(require("react"));
78
79
  var react_toastify_1 = require("react-toastify");
79
80
  var CustomButton_1 = __importDefault(require("./CustomButton"));
@@ -120,6 +121,7 @@ var CustomForm = function (_a) {
120
121
  var formRef = (0, react_1.useRef)(null);
121
122
  var _f = (0, react_1.useState)(false), isLoading = _f[0], setIsLoading = _f[1];
122
123
  var _g = (0, react_1.useState)(false), submitted = _g[0], setSubmitted = _g[1];
124
+ var _h = (0, react_1.useState)(false), isUploading = _h[0], setIsUploading = _h[1];
123
125
  var handleConfirm = function (e) { return __awaiter(void 0, void 0, void 0, function () {
124
126
  var form, customSelectValid, isValid, formValues_1, error_1;
125
127
  return __generator(this, function (_a) {
@@ -228,14 +230,14 @@ var CustomForm = function (_a) {
228
230
  return (react_1.default.createElement("div", { className: "row ".concat(innerRowCustomClass), key: "inner-row-".concat(rowId, "-").concat(colId, "-").concat(innerRowId) }, elements.map(function (element) { return (react_1.default.createElement("div", { className: element.colClass || "col-12", key: element.id }, element.type === ElementType.TEXT ? (react_1.default.createElement(CustomText_1.default, __assign({}, element))) : element.type === ElementType.INPUT ? (react_1.default.createElement(CustomInput_1.default, __assign({}, element))) : element.type === ElementType.TEXTAREA ? (react_1.default.createElement(CustomTextarea_1.default, __assign({}, element))) : element.type === ElementType.CHECKBOX ? (react_1.default.createElement(CustomCheckbox_1.default, __assign({}, element))) : element.type === ElementType.RADIO ? (react_1.default.createElement(CustomRadioButton_1.default, __assign({}, element))) : element.type === ElementType.SELECT ? (react_1.default.createElement(CustomSelect_1.default, __assign({}, element, { submitted: submitted }))) : element.type === ElementType.SIMPLESELECT ? (react_1.default.createElement(CustomSimpleSelect_1.default, __assign({}, element, { value: Array.isArray(element.value) ? element.value[0] || "" : "", onChange: function (val) { return element.onChange(val); } }))) : 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))) : 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 ? (
229
231
  // FILEUPLOADER elemanı için CustomFileUploader'ı render ediyoruz
230
232
  react_1.default.createElement(react_1.default.Fragment, null,
231
- 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 }))) : null)); })));
233
+ 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)); })));
232
234
  })));
233
235
  })));
234
236
  }),
235
237
  (showConfirmButton || showCancelButton) && (react_1.default.createElement("div", { className: "card-footer mt-3" },
236
238
  react_1.default.createElement("div", { className: "form-actions mt-3", style: { display: "flex", justifyContent: "flex-end", gap: "10px" } },
237
- showCancelButton && (react_1.default.createElement(CustomButton_1.default, { label: cancelLabel, className: "btn btn-secondary", onClick: handleCancel || (function () { }), isLoading: isLoading })),
238
- showConfirmButton && (react_1.default.createElement(CustomButton_1.default, { label: confirmLabel, className: "btn btn-primary", onClick: handleConfirm, isLoading: isLoading })))))));
239
+ showCancelButton && (react_1.default.createElement(CustomButton_1.default, { label: cancelLabel, className: "btn btn-secondary", onClick: handleCancel || (function () { }), isLoading: isLoading || isUploading })),
240
+ showConfirmButton && (react_1.default.createElement(CustomButton_1.default, { label: confirmLabel, className: "btn btn-primary", onClick: handleConfirm, isLoading: isLoading || isUploading })))))));
239
241
  };
240
242
  exports.CustomForm = CustomForm;
241
243
  exports.default = CustomForm;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "albinasoft-ui-package",
3
- "version": "1.1.36",
3
+ "version": "1.1.38",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {