@teselagen/ui 0.5.23-beta.32 → 0.5.23-beta.33

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.
@@ -1,5 +1,5 @@
1
1
  export default Uploader;
2
- declare function Uploader({ accept: __accept, action, autoUnzip, beforeUpload, callout: _callout, className, contentOverride: maybeContentOverride, disabled: _disabled, dropzoneProps, fileLimit, fileList, innerIcon, innerText, meta: { form: formName }, minimal, name, noBuildCsvOption, noRedux, onChange: _onChange, onFieldSubmit, onFileClick, onFileSuccess, onPreviewClick, onRemove, overflowList, readBeforeUpload, showFilesCount, showUploadList, threeDotMenuItems, validateAgainstSchema: _validateAgainstSchema }: {
2
+ declare function Uploader({ accept: __accept, action, autoUnzip, beforeUpload, callout: _callout, className, contentOverride: maybeContentOverride, disabled, dropzoneProps, fileLimit, fileList, innerIcon, innerText, meta: { form: formName }, minimal, name, noBuildCsvOption, noRedux, onChange: _onChange, onFieldSubmit, onFileClick, onFileSuccess, onPreviewClick, onRemove, overflowList, readBeforeUpload, showFilesCount, showUploadList, threeDotMenuItems, validateAgainstSchema: _validateAgainstSchema }: {
3
3
  accept: any;
4
4
  action: any;
5
5
  autoUnzip: any;
package/index.cjs.js CHANGED
@@ -31035,7 +31035,7 @@ const _TgSelect = class _TgSelect extends React$1.Component {
31035
31035
  e2.preventDefault();
31036
31036
  let newValue = null;
31037
31037
  if (multi) {
31038
- newValue = filter(value, (obj) => obj.disabled) || [];
31038
+ newValue = filter(value, (obj) => obj == null ? void 0 : obj.disabled) || [];
31039
31039
  } else if (value && value.disabled) {
31040
31040
  newValue = value;
31041
31041
  }
@@ -67399,6 +67399,9 @@ const InnerDropZone = /* @__PURE__ */ __name(({
67399
67399
  )
67400
67400
  )
67401
67401
  ), showFilesCount ? /* @__PURE__ */ React$1.createElement("div", { className: "tg-upload-file-list-counter" }, "Files: ", fileList ? fileList.length : 0) : null), "InnerDropZone");
67402
+ const onFileSuccessDefault = /* @__PURE__ */ __name(() => __async(exports, null, function* () {
67403
+ return;
67404
+ }), "onFileSuccessDefault");
67402
67405
  const Uploader = /* @__PURE__ */ __name(({
67403
67406
  accept: __accept,
67404
67407
  action: action2,
@@ -67407,7 +67410,7 @@ const Uploader = /* @__PURE__ */ __name(({
67407
67410
  callout: _callout,
67408
67411
  className = "",
67409
67412
  contentOverride: maybeContentOverride,
67410
- disabled: _disabled,
67413
+ disabled,
67411
67414
  dropzoneProps = {},
67412
67415
  fileLimit,
67413
67416
  fileList,
@@ -67425,9 +67428,7 @@ const Uploader = /* @__PURE__ */ __name(({
67425
67428
  //called when all files have successfully uploaded
67426
67429
  onFileClick,
67427
67430
  // called when a file link in the filelist is clicked
67428
- onFileSuccess = /* @__PURE__ */ __name(() => __async(exports, null, function* () {
67429
- return;
67430
- }), "onFileSuccess"),
67431
+ onFileSuccess = onFileSuccessDefault,
67431
67432
  //called each time a file is finished and before the file.loading gets set to false, needs to return a promise!
67432
67433
  onPreviewClick,
67433
67434
  onRemove = noop$4,
@@ -67446,83 +67447,92 @@ const Uploader = /* @__PURE__ */ __name(({
67446
67447
  const [resolvedAccept, setResolvedAccept] = React$1.useState();
67447
67448
  const [loading, setLoading] = React$1.useState(false);
67448
67449
  const filesToClean = React$1.useRef([]);
67449
- const onChange = /* @__PURE__ */ __name((val) => {
67450
- require$$2$1.flushSync(() => {
67451
- if (noRedux) {
67452
- return _onChange(val);
67453
- }
67454
- dispatch(reduxForm.touch(formName, name));
67455
- dispatch(reduxForm.change(formName, name, val));
67456
- });
67457
- }, "onChange");
67458
- const handleSecondHalfOfUpload = /* @__PURE__ */ __name((_0) => __async(exports, [_0], function* ({
67459
- acceptedFiles,
67460
- cleanedFileList
67461
- }) {
67462
- onChange(cleanedFileList);
67463
- const keepGoing = beforeUpload ? yield beforeUpload(cleanedFileList, onChange) : true;
67464
- if (!keepGoing)
67465
- return;
67466
- if (action2) {
67467
- const responses = [];
67468
- yield Promise.all(
67469
- acceptedFiles.map((fileToUpload) => __async(exports, null, function* () {
67470
- const data = new FormData();
67471
- data.append("file", fileToUpload);
67472
- try {
67473
- const res = yield window.serverApi ? window.serverApi.post(action2, data) : fetch(action2, {
67474
- method: "POST",
67475
- body: data
67476
- });
67477
- responses.push(res.data && res.data[0]);
67478
- onFileSuccess(res.data[0]).then(() => {
67450
+ const stableOnChange = useStableReference(_onChange);
67451
+ const stableBeforeUpload = useStableReference(beforeUpload);
67452
+ const onChange = React$1.useCallback(
67453
+ (val) => {
67454
+ require$$2$1.flushSync(() => {
67455
+ if (noRedux) {
67456
+ return stableOnChange.current(val);
67457
+ }
67458
+ dispatch(reduxForm.touch(formName, name));
67459
+ dispatch(reduxForm.change(formName, name, val));
67460
+ });
67461
+ },
67462
+ [dispatch, formName, name, noRedux, stableOnChange]
67463
+ );
67464
+ const handleSecondHalfOfUpload = React$1.useCallback(
67465
+ (_0) => __async(exports, [_0], function* ({ acceptedFiles, cleanedFileList }) {
67466
+ onChange(cleanedFileList);
67467
+ const keepGoing = stableBeforeUpload.current ? yield stableBeforeUpload.current(cleanedFileList, onChange) : true;
67468
+ if (!keepGoing)
67469
+ return;
67470
+ if (action2) {
67471
+ const responses = [];
67472
+ yield Promise.all(
67473
+ acceptedFiles.map((fileToUpload) => __async(exports, null, function* () {
67474
+ const data = new FormData();
67475
+ data.append("file", fileToUpload);
67476
+ try {
67477
+ const res = yield window.serverApi ? window.serverApi.post(action2, data) : fetch(action2, {
67478
+ method: "POST",
67479
+ body: data
67480
+ });
67481
+ responses.push(res.data && res.data[0]);
67482
+ onFileSuccess(res.data[0]).then(() => {
67483
+ cleanedFileList = cleanedFileList.map((file) => {
67484
+ const fileToReturn = __spreadValues(__spreadValues({}, file), res.data[0]);
67485
+ if (fileToReturn.id === fileToUpload.id) {
67486
+ fileToReturn.loading = false;
67487
+ }
67488
+ return fileToReturn;
67489
+ });
67490
+ onChange(cleanedFileList);
67491
+ });
67492
+ } catch (err) {
67493
+ console.error("Error uploading file:", err);
67494
+ responses.push(__spreadProps(__spreadValues({}, fileToUpload), {
67495
+ error: err && err.msg ? err.msg : err
67496
+ }));
67479
67497
  cleanedFileList = cleanedFileList.map((file) => {
67480
- const fileToReturn = __spreadValues(__spreadValues({}, file), res.data[0]);
67498
+ const fileToReturn = __spreadValues({}, file);
67481
67499
  if (fileToReturn.id === fileToUpload.id) {
67482
67500
  fileToReturn.loading = false;
67501
+ fileToReturn.error = true;
67483
67502
  }
67484
67503
  return fileToReturn;
67485
67504
  });
67486
67505
  onChange(cleanedFileList);
67506
+ }
67507
+ }))
67508
+ );
67509
+ onFieldSubmit(responses);
67510
+ } else {
67511
+ onChange(
67512
+ cleanedFileList.map(function(file) {
67513
+ return __spreadProps(__spreadValues({}, file), {
67514
+ loading: false
67487
67515
  });
67488
- } catch (err) {
67489
- console.error("Error uploading file:", err);
67490
- responses.push(__spreadProps(__spreadValues({}, fileToUpload), {
67491
- error: err && err.msg ? err.msg : err
67492
- }));
67493
- cleanedFileList = cleanedFileList.map((file) => {
67494
- const fileToReturn = __spreadValues({}, file);
67495
- if (fileToReturn.id === fileToUpload.id) {
67496
- fileToReturn.loading = false;
67497
- fileToReturn.error = true;
67498
- }
67499
- return fileToReturn;
67500
- });
67501
- onChange(cleanedFileList);
67502
- }
67503
- }))
67504
- );
67505
- onFieldSubmit(responses);
67506
- } else {
67507
- onChange(
67508
- cleanedFileList.map(function(file) {
67509
- return __spreadProps(__spreadValues({}, file), {
67510
- loading: false
67511
- });
67512
- })
67513
- );
67514
- }
67515
- setLoading(false);
67516
- }), "handleSecondHalfOfUpload");
67516
+ })
67517
+ );
67518
+ }
67519
+ setLoading(false);
67520
+ }),
67521
+ [action2, stableBeforeUpload, onChange, onFieldSubmit, onFileSuccess]
67522
+ );
67517
67523
  const isAcceptPromise = React$1.useMemo(
67518
67524
  () => (__accept == null ? void 0 : __accept.then) || (Array.isArray(__accept) ? __accept.some((acc) => acc == null ? void 0 : acc.then) : false),
67519
67525
  [__accept]
67520
67526
  );
67521
- let dropzoneDisabled = _disabled;
67522
- let _accept = __accept;
67523
- if (resolvedAccept) {
67524
- _accept = resolvedAccept;
67525
- }
67527
+ const _accept = React$1.useMemo(() => {
67528
+ if (resolvedAccept) {
67529
+ return resolvedAccept;
67530
+ }
67531
+ if (isAcceptPromise && !resolvedAccept) {
67532
+ return [];
67533
+ }
67534
+ return __accept;
67535
+ }, [__accept, isAcceptPromise, resolvedAccept]);
67526
67536
  React$1.useEffect(() => {
67527
67537
  if (isAcceptPromise) {
67528
67538
  setAcceptLoading(true);
@@ -67535,9 +67545,7 @@ const Uploader = /* @__PURE__ */ __name(({
67535
67545
  );
67536
67546
  }
67537
67547
  }, [__accept, isAcceptPromise]);
67538
- if (isAcceptPromise && !resolvedAccept) {
67539
- _accept = [];
67540
- }
67548
+ let dropzoneDisabled = disabled;
67541
67549
  if (acceptLoading)
67542
67550
  dropzoneDisabled = true;
67543
67551
  const accept = React$1.useMemo(
@@ -67762,7 +67770,7 @@ const Uploader = /* @__PURE__ */ __name(({
67762
67770
  style: { fontSize: 11, marginBottom: 5 }
67763
67771
  },
67764
67772
  advancedAccept && !acceptLoading ? /* @__PURE__ */ React$1.createElement("div", null, "Accepts  ", /* @__PURE__ */ React$1.createElement("span", null, advancedAccept.map((acc, i) => {
67765
- const disabled = !(acc.description || acc.exampleFile || acc.exampleFiles);
67773
+ const disabled2 = !(acc.description || acc.exampleFile || acc.exampleFiles);
67766
67774
  const PopOrTooltip = acc.exampleFiles ? core.Popover : core.Tooltip;
67767
67775
  const hasDownload = acc.exampleFile || acc.exampleFiles;
67768
67776
  const CustomTag = !hasDownload ? "span" : "a";
@@ -67771,7 +67779,7 @@ const Uploader = /* @__PURE__ */ __name(({
67771
67779
  {
67772
67780
  key: i,
67773
67781
  interactionKind: "hover",
67774
- disabled,
67782
+ disabled: disabled2,
67775
67783
  modifiers: popoverOverflowModifiers,
67776
67784
  content: acc.exampleFiles ? /* @__PURE__ */ React$1.createElement(core.Menu, null, acc.exampleFiles.map(
67777
67785
  ({ description, subtext, exampleFile, icon }, i2) => /* @__PURE__ */ React$1.createElement(
package/index.es.js CHANGED
@@ -31017,7 +31017,7 @@ const _TgSelect = class _TgSelect extends React__default.Component {
31017
31017
  e2.preventDefault();
31018
31018
  let newValue = null;
31019
31019
  if (multi) {
31020
- newValue = filter(value, (obj) => obj.disabled) || [];
31020
+ newValue = filter(value, (obj) => obj == null ? void 0 : obj.disabled) || [];
31021
31021
  } else if (value && value.disabled) {
31022
31022
  newValue = value;
31023
31023
  }
@@ -67381,6 +67381,9 @@ const InnerDropZone = /* @__PURE__ */ __name(({
67381
67381
  )
67382
67382
  )
67383
67383
  ), showFilesCount ? /* @__PURE__ */ React__default.createElement("div", { className: "tg-upload-file-list-counter" }, "Files: ", fileList ? fileList.length : 0) : null), "InnerDropZone");
67384
+ const onFileSuccessDefault = /* @__PURE__ */ __name(() => __async(void 0, null, function* () {
67385
+ return;
67386
+ }), "onFileSuccessDefault");
67384
67387
  const Uploader = /* @__PURE__ */ __name(({
67385
67388
  accept: __accept,
67386
67389
  action: action2,
@@ -67389,7 +67392,7 @@ const Uploader = /* @__PURE__ */ __name(({
67389
67392
  callout: _callout,
67390
67393
  className = "",
67391
67394
  contentOverride: maybeContentOverride,
67392
- disabled: _disabled,
67395
+ disabled,
67393
67396
  dropzoneProps = {},
67394
67397
  fileLimit,
67395
67398
  fileList,
@@ -67407,9 +67410,7 @@ const Uploader = /* @__PURE__ */ __name(({
67407
67410
  //called when all files have successfully uploaded
67408
67411
  onFileClick,
67409
67412
  // called when a file link in the filelist is clicked
67410
- onFileSuccess = /* @__PURE__ */ __name(() => __async(void 0, null, function* () {
67411
- return;
67412
- }), "onFileSuccess"),
67413
+ onFileSuccess = onFileSuccessDefault,
67413
67414
  //called each time a file is finished and before the file.loading gets set to false, needs to return a promise!
67414
67415
  onPreviewClick,
67415
67416
  onRemove = noop$4,
@@ -67428,83 +67429,92 @@ const Uploader = /* @__PURE__ */ __name(({
67428
67429
  const [resolvedAccept, setResolvedAccept] = useState();
67429
67430
  const [loading, setLoading] = useState(false);
67430
67431
  const filesToClean = useRef([]);
67431
- const onChange = /* @__PURE__ */ __name((val) => {
67432
- flushSync(() => {
67433
- if (noRedux) {
67434
- return _onChange(val);
67435
- }
67436
- dispatch(touch(formName, name));
67437
- dispatch(change(formName, name, val));
67438
- });
67439
- }, "onChange");
67440
- const handleSecondHalfOfUpload = /* @__PURE__ */ __name((_0) => __async(void 0, [_0], function* ({
67441
- acceptedFiles,
67442
- cleanedFileList
67443
- }) {
67444
- onChange(cleanedFileList);
67445
- const keepGoing = beforeUpload ? yield beforeUpload(cleanedFileList, onChange) : true;
67446
- if (!keepGoing)
67447
- return;
67448
- if (action2) {
67449
- const responses = [];
67450
- yield Promise.all(
67451
- acceptedFiles.map((fileToUpload) => __async(void 0, null, function* () {
67452
- const data = new FormData();
67453
- data.append("file", fileToUpload);
67454
- try {
67455
- const res = yield window.serverApi ? window.serverApi.post(action2, data) : fetch(action2, {
67456
- method: "POST",
67457
- body: data
67458
- });
67459
- responses.push(res.data && res.data[0]);
67460
- onFileSuccess(res.data[0]).then(() => {
67432
+ const stableOnChange = useStableReference(_onChange);
67433
+ const stableBeforeUpload = useStableReference(beforeUpload);
67434
+ const onChange = useCallback(
67435
+ (val) => {
67436
+ flushSync(() => {
67437
+ if (noRedux) {
67438
+ return stableOnChange.current(val);
67439
+ }
67440
+ dispatch(touch(formName, name));
67441
+ dispatch(change(formName, name, val));
67442
+ });
67443
+ },
67444
+ [dispatch, formName, name, noRedux, stableOnChange]
67445
+ );
67446
+ const handleSecondHalfOfUpload = useCallback(
67447
+ (_0) => __async(void 0, [_0], function* ({ acceptedFiles, cleanedFileList }) {
67448
+ onChange(cleanedFileList);
67449
+ const keepGoing = stableBeforeUpload.current ? yield stableBeforeUpload.current(cleanedFileList, onChange) : true;
67450
+ if (!keepGoing)
67451
+ return;
67452
+ if (action2) {
67453
+ const responses = [];
67454
+ yield Promise.all(
67455
+ acceptedFiles.map((fileToUpload) => __async(void 0, null, function* () {
67456
+ const data = new FormData();
67457
+ data.append("file", fileToUpload);
67458
+ try {
67459
+ const res = yield window.serverApi ? window.serverApi.post(action2, data) : fetch(action2, {
67460
+ method: "POST",
67461
+ body: data
67462
+ });
67463
+ responses.push(res.data && res.data[0]);
67464
+ onFileSuccess(res.data[0]).then(() => {
67465
+ cleanedFileList = cleanedFileList.map((file) => {
67466
+ const fileToReturn = __spreadValues(__spreadValues({}, file), res.data[0]);
67467
+ if (fileToReturn.id === fileToUpload.id) {
67468
+ fileToReturn.loading = false;
67469
+ }
67470
+ return fileToReturn;
67471
+ });
67472
+ onChange(cleanedFileList);
67473
+ });
67474
+ } catch (err) {
67475
+ console.error("Error uploading file:", err);
67476
+ responses.push(__spreadProps(__spreadValues({}, fileToUpload), {
67477
+ error: err && err.msg ? err.msg : err
67478
+ }));
67461
67479
  cleanedFileList = cleanedFileList.map((file) => {
67462
- const fileToReturn = __spreadValues(__spreadValues({}, file), res.data[0]);
67480
+ const fileToReturn = __spreadValues({}, file);
67463
67481
  if (fileToReturn.id === fileToUpload.id) {
67464
67482
  fileToReturn.loading = false;
67483
+ fileToReturn.error = true;
67465
67484
  }
67466
67485
  return fileToReturn;
67467
67486
  });
67468
67487
  onChange(cleanedFileList);
67488
+ }
67489
+ }))
67490
+ );
67491
+ onFieldSubmit(responses);
67492
+ } else {
67493
+ onChange(
67494
+ cleanedFileList.map(function(file) {
67495
+ return __spreadProps(__spreadValues({}, file), {
67496
+ loading: false
67469
67497
  });
67470
- } catch (err) {
67471
- console.error("Error uploading file:", err);
67472
- responses.push(__spreadProps(__spreadValues({}, fileToUpload), {
67473
- error: err && err.msg ? err.msg : err
67474
- }));
67475
- cleanedFileList = cleanedFileList.map((file) => {
67476
- const fileToReturn = __spreadValues({}, file);
67477
- if (fileToReturn.id === fileToUpload.id) {
67478
- fileToReturn.loading = false;
67479
- fileToReturn.error = true;
67480
- }
67481
- return fileToReturn;
67482
- });
67483
- onChange(cleanedFileList);
67484
- }
67485
- }))
67486
- );
67487
- onFieldSubmit(responses);
67488
- } else {
67489
- onChange(
67490
- cleanedFileList.map(function(file) {
67491
- return __spreadProps(__spreadValues({}, file), {
67492
- loading: false
67493
- });
67494
- })
67495
- );
67496
- }
67497
- setLoading(false);
67498
- }), "handleSecondHalfOfUpload");
67498
+ })
67499
+ );
67500
+ }
67501
+ setLoading(false);
67502
+ }),
67503
+ [action2, stableBeforeUpload, onChange, onFieldSubmit, onFileSuccess]
67504
+ );
67499
67505
  const isAcceptPromise = useMemo(
67500
67506
  () => (__accept == null ? void 0 : __accept.then) || (Array.isArray(__accept) ? __accept.some((acc) => acc == null ? void 0 : acc.then) : false),
67501
67507
  [__accept]
67502
67508
  );
67503
- let dropzoneDisabled = _disabled;
67504
- let _accept = __accept;
67505
- if (resolvedAccept) {
67506
- _accept = resolvedAccept;
67507
- }
67509
+ const _accept = useMemo(() => {
67510
+ if (resolvedAccept) {
67511
+ return resolvedAccept;
67512
+ }
67513
+ if (isAcceptPromise && !resolvedAccept) {
67514
+ return [];
67515
+ }
67516
+ return __accept;
67517
+ }, [__accept, isAcceptPromise, resolvedAccept]);
67508
67518
  useEffect(() => {
67509
67519
  if (isAcceptPromise) {
67510
67520
  setAcceptLoading(true);
@@ -67517,9 +67527,7 @@ const Uploader = /* @__PURE__ */ __name(({
67517
67527
  );
67518
67528
  }
67519
67529
  }, [__accept, isAcceptPromise]);
67520
- if (isAcceptPromise && !resolvedAccept) {
67521
- _accept = [];
67522
- }
67530
+ let dropzoneDisabled = disabled;
67523
67531
  if (acceptLoading)
67524
67532
  dropzoneDisabled = true;
67525
67533
  const accept = useMemo(
@@ -67744,7 +67752,7 @@ const Uploader = /* @__PURE__ */ __name(({
67744
67752
  style: { fontSize: 11, marginBottom: 5 }
67745
67753
  },
67746
67754
  advancedAccept && !acceptLoading ? /* @__PURE__ */ React__default.createElement("div", null, "Accepts  ", /* @__PURE__ */ React__default.createElement("span", null, advancedAccept.map((acc, i) => {
67747
- const disabled = !(acc.description || acc.exampleFile || acc.exampleFiles);
67755
+ const disabled2 = !(acc.description || acc.exampleFile || acc.exampleFiles);
67748
67756
  const PopOrTooltip = acc.exampleFiles ? Popover : Tooltip;
67749
67757
  const hasDownload = acc.exampleFile || acc.exampleFiles;
67750
67758
  const CustomTag = !hasDownload ? "span" : "a";
@@ -67753,7 +67761,7 @@ const Uploader = /* @__PURE__ */ __name(({
67753
67761
  {
67754
67762
  key: i,
67755
67763
  interactionKind: "hover",
67756
- disabled,
67764
+ disabled: disabled2,
67757
67765
  modifiers: popoverOverflowModifiers,
67758
67766
  content: acc.exampleFiles ? /* @__PURE__ */ React__default.createElement(Menu, null, acc.exampleFiles.map(
67759
67767
  ({ description, subtext, exampleFile, icon }, i2) => /* @__PURE__ */ React__default.createElement(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teselagen/ui",
3
- "version": "0.5.23-beta.32",
3
+ "version": "0.5.23-beta.33",
4
4
  "main": "./src/index.js",
5
5
  "exports": {
6
6
  ".": {
@@ -1,4 +1,10 @@
1
- import React, { useEffect, useMemo, useRef, useState } from "react";
1
+ import React, {
2
+ useCallback,
3
+ useEffect,
4
+ useMemo,
5
+ useRef,
6
+ useState
7
+ } from "react";
2
8
  import {
3
9
  Button,
4
10
  Callout,
@@ -42,6 +48,7 @@ import convertSchema from "../DataTable/utils/convertSchema";
42
48
  import { LoadingDots } from "./LoadingDots";
43
49
  import { useDispatch } from "react-redux";
44
50
  import { flushSync } from "react-dom";
51
+ import { useStableReference } from "../utils/hooks/useStableReference";
45
52
 
46
53
  const manualEnterMessage = "Build CSV File";
47
54
  const manualEnterSubMessage = "Paste or type data to build a CSV file";
@@ -208,6 +215,10 @@ const InnerDropZone = ({
208
215
  </section>
209
216
  );
210
217
 
218
+ const onFileSuccessDefault = async () => {
219
+ return;
220
+ };
221
+
211
222
  const Uploader = ({
212
223
  accept: __accept,
213
224
  action,
@@ -216,7 +227,7 @@ const Uploader = ({
216
227
  callout: _callout,
217
228
  className = "",
218
229
  contentOverride: maybeContentOverride,
219
- disabled: _disabled,
230
+ disabled,
220
231
  dropzoneProps = {},
221
232
  fileLimit,
222
233
  fileList, //list of files with options: {name, loading, error, url, originalName, downloadName}
@@ -230,9 +241,7 @@ const Uploader = ({
230
241
  onChange: _onChange = noop, //this is almost always getting passed by redux-form, no need to pass this handler manually
231
242
  onFieldSubmit = noop, //called when all files have successfully uploaded
232
243
  onFileClick, // called when a file link in the filelist is clicked
233
- onFileSuccess = async () => {
234
- return;
235
- }, //called each time a file is finished and before the file.loading gets set to false, needs to return a promise!
244
+ onFileSuccess = onFileSuccessDefault, //called each time a file is finished and before the file.loading gets set to false, needs to return a promise!
236
245
  onPreviewClick,
237
246
  onRemove = noop, //called when a file has been selected to be removed
238
247
  overflowList,
@@ -247,88 +256,95 @@ const Uploader = ({
247
256
  const [resolvedAccept, setResolvedAccept] = useState();
248
257
  const [loading, setLoading] = useState(false);
249
258
  const filesToClean = useRef([]);
259
+
260
+ // We do this because we don't want functions influencing on the dependencies
261
+ const stableOnChange = useStableReference(_onChange);
262
+ const stableBeforeUpload = useStableReference(beforeUpload);
250
263
  // onChange received from redux-form is not working anymore,
251
264
  // so we need to overwrite it for redux to works.
252
- const onChange = val => {
253
- flushSync(() => {
254
- if (noRedux) {
255
- return _onChange(val);
256
- }
257
- dispatch(touch(formName, name));
258
- dispatch(change(formName, name, val));
259
- });
260
- };
265
+ const onChange = useCallback(
266
+ val => {
267
+ flushSync(() => {
268
+ if (noRedux) {
269
+ return stableOnChange.current(val);
270
+ }
271
+ dispatch(touch(formName, name));
272
+ dispatch(change(formName, name, val));
273
+ });
274
+ },
275
+ [dispatch, formName, name, noRedux, stableOnChange]
276
+ );
261
277
 
262
- const handleSecondHalfOfUpload = async ({
263
- acceptedFiles,
264
- cleanedFileList
265
- }) => {
266
- // This onChange is not changing things, we need to check whether the error is here or later
267
- onChange(cleanedFileList); //tnw: this line is necessary, if you want to clear the file list in the beforeUpload, call onChange([])
268
- // beforeUpload is called, otherwise beforeUpload will not be able to truly cancel the upload
269
- const keepGoing = beforeUpload
270
- ? await beforeUpload(cleanedFileList, onChange)
271
- : true;
272
- if (!keepGoing) return;
278
+ const handleSecondHalfOfUpload = useCallback(
279
+ async ({ acceptedFiles, cleanedFileList }) => {
280
+ // This onChange is not changing things, we need to check whether the error is here or later
281
+ onChange(cleanedFileList); //tnw: this line is necessary, if you want to clear the file list in the beforeUpload, call onChange([])
282
+ // beforeUpload is called, otherwise beforeUpload will not be able to truly cancel the upload
283
+ const keepGoing = stableBeforeUpload.current
284
+ ? await stableBeforeUpload.current(cleanedFileList, onChange)
285
+ : true;
286
+ if (!keepGoing) return;
273
287
 
274
- if (action) {
275
- const responses = [];
276
- await Promise.all(
277
- acceptedFiles.map(async fileToUpload => {
278
- const data = new FormData();
279
- data.append("file", fileToUpload);
280
- try {
281
- const res = await (window.serverApi
282
- ? window.serverApi.post(action, data)
283
- : fetch(action, {
284
- method: "POST",
285
- body: data
286
- }));
287
- responses.push(res.data && res.data[0]);
288
- onFileSuccess(res.data[0]).then(() => {
288
+ if (action) {
289
+ const responses = [];
290
+ await Promise.all(
291
+ acceptedFiles.map(async fileToUpload => {
292
+ const data = new FormData();
293
+ data.append("file", fileToUpload);
294
+ try {
295
+ const res = await (window.serverApi
296
+ ? window.serverApi.post(action, data)
297
+ : fetch(action, {
298
+ method: "POST",
299
+ body: data
300
+ }));
301
+ responses.push(res.data && res.data[0]);
302
+ onFileSuccess(res.data[0]).then(() => {
303
+ cleanedFileList = cleanedFileList.map(file => {
304
+ const fileToReturn = {
305
+ ...file,
306
+ ...res.data[0]
307
+ };
308
+ if (fileToReturn.id === fileToUpload.id) {
309
+ fileToReturn.loading = false;
310
+ }
311
+ return fileToReturn;
312
+ });
313
+ onChange(cleanedFileList);
314
+ });
315
+ } catch (err) {
316
+ console.error("Error uploading file:", err);
317
+ responses.push({
318
+ ...fileToUpload,
319
+ error: err && err.msg ? err.msg : err
320
+ });
289
321
  cleanedFileList = cleanedFileList.map(file => {
290
- const fileToReturn = {
291
- ...file,
292
- ...res.data[0]
293
- };
322
+ const fileToReturn = { ...file };
294
323
  if (fileToReturn.id === fileToUpload.id) {
295
324
  fileToReturn.loading = false;
325
+ fileToReturn.error = true;
296
326
  }
297
327
  return fileToReturn;
298
328
  });
299
329
  onChange(cleanedFileList);
300
- });
301
- } catch (err) {
302
- console.error("Error uploading file:", err);
303
- responses.push({
304
- ...fileToUpload,
305
- error: err && err.msg ? err.msg : err
306
- });
307
- cleanedFileList = cleanedFileList.map(file => {
308
- const fileToReturn = { ...file };
309
- if (fileToReturn.id === fileToUpload.id) {
310
- fileToReturn.loading = false;
311
- fileToReturn.error = true;
312
- }
313
- return fileToReturn;
314
- });
315
- onChange(cleanedFileList);
316
- }
317
- })
318
- );
319
- onFieldSubmit(responses);
320
- } else {
321
- onChange(
322
- cleanedFileList.map(function (file) {
323
- return {
324
- ...file,
325
- loading: false
326
- };
327
- })
328
- );
329
- }
330
- setLoading(false);
331
- };
330
+ }
331
+ })
332
+ );
333
+ onFieldSubmit(responses);
334
+ } else {
335
+ onChange(
336
+ cleanedFileList.map(function (file) {
337
+ return {
338
+ ...file,
339
+ loading: false
340
+ };
341
+ })
342
+ );
343
+ }
344
+ setLoading(false);
345
+ },
346
+ [action, stableBeforeUpload, onChange, onFieldSubmit, onFileSuccess]
347
+ );
332
348
 
333
349
  const isAcceptPromise = useMemo(
334
350
  () =>
@@ -337,12 +353,15 @@ const Uploader = ({
337
353
  [__accept]
338
354
  );
339
355
 
340
- let dropzoneDisabled = _disabled;
341
- let _accept = __accept;
342
-
343
- if (resolvedAccept) {
344
- _accept = resolvedAccept;
345
- }
356
+ const _accept = useMemo(() => {
357
+ if (resolvedAccept) {
358
+ return resolvedAccept;
359
+ }
360
+ if (isAcceptPromise && !resolvedAccept) {
361
+ return [];
362
+ }
363
+ return __accept;
364
+ }, [__accept, isAcceptPromise, resolvedAccept]);
346
365
 
347
366
  useEffect(() => {
348
367
  if (isAcceptPromise) {
@@ -357,11 +376,9 @@ const Uploader = ({
357
376
  }
358
377
  }, [__accept, isAcceptPromise]);
359
378
 
360
- if (isAcceptPromise && !resolvedAccept) {
361
- _accept = [];
362
- }
363
-
379
+ let dropzoneDisabled = disabled;
364
380
  if (acceptLoading) dropzoneDisabled = true;
381
+
365
382
  const accept = useMemo(
366
383
  () =>
367
384
  !_accept
@@ -126,7 +126,7 @@ class TgSelect extends React.Component {
126
126
  e.preventDefault();
127
127
  let newValue = null;
128
128
  if (multi) {
129
- newValue = filter(value, obj => obj.disabled) || [];
129
+ newValue = filter(value, obj => obj?.disabled) || [];
130
130
  } else if (value && value.disabled) {
131
131
  newValue = value;
132
132
  }