@teselagen/ui 0.5.23-beta.31 → 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.
- package/DataTable/utils/index.d.ts +1 -2
- package/FormComponents/Uploader.d.ts +1 -1
- package/index.cjs.js +103 -86
- package/index.d.ts +2 -1
- package/index.es.js +103 -86
- package/package.json +1 -1
- package/src/DataTable/EditabelCell.js +4 -4
- package/src/DataTable/index.js +2 -2
- package/src/DataTable/utils/index.js +0 -2
- package/src/DataTable/utils/useTableParams.js +0 -1
- package/src/DataTable/utils/withTableParams.js +1 -1
- package/src/FormComponents/Uploader.js +103 -86
- package/src/FormComponents/index.js +8 -4
- package/src/TgSelect/index.js +1 -1
- package/src/UploadCsvWizard.js +2 -1
- package/src/index.js +2 -1
- package/src/utils/hooks/index.js +1 -0
- package/src/utils/hooks/useDeepEqualMemo.js +10 -0
- package/src/utils/hooks/useStableReference.js +9 -0
- package/utils/hooks/index.d.ts +1 -0
- package/utils/hooks/useDeepEqualMemo.d.ts +1 -0
- package/utils/hooks/useStableReference.d.ts +1 -0
- package/FormComponents/AbstractField.d.ts +0 -1
- package/src/FormComponents/AbstractField.js +0 -388
|
@@ -24,7 +24,6 @@ import { handleCopyColumn } from "./handleCopyColumn";
|
|
|
24
24
|
import { isBottomRightCornerOfRectangle } from "./isBottomRightCornerOfRectangle";
|
|
25
25
|
import { handleCopyTable } from "./handleCopyTable";
|
|
26
26
|
import { PRIMARY_SELECTED_VAL } from "./primarySelectedValue";
|
|
27
|
-
import { useDeepEqualMemo } from "./useDeepEqualMemo";
|
|
28
27
|
import { useTableEntities } from "./useTableEntities";
|
|
29
28
|
|
|
30
29
|
export {
|
|
@@ -52,6 +51,5 @@ export {
|
|
|
52
51
|
PRIMARY_SELECTED_VAL,
|
|
53
52
|
removeCleanRows,
|
|
54
53
|
stripNumberAtEnd,
|
|
55
|
-
useDeepEqualMemo,
|
|
56
54
|
useTableEntities
|
|
57
55
|
};
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./queryParams";
|
|
12
12
|
import { withRouter } from "react-router-dom";
|
|
13
13
|
import getTableConfigFromStorage from "./getTableConfigFromStorage";
|
|
14
|
-
import { useDeepEqualMemo } from "
|
|
14
|
+
import { useDeepEqualMemo } from "../../utils/hooks/useDeepEqualMemo";
|
|
15
15
|
import { branch, compose } from "recompose";
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import 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
|
|
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 =
|
|
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 =
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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 =
|
|
263
|
-
acceptedFiles,
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
-
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
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
|
-
|
|
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
|
|
@@ -46,6 +46,7 @@ import Uploader from "./Uploader";
|
|
|
46
46
|
import sortify from "./sortify";
|
|
47
47
|
import { fieldRequired } from "./utils";
|
|
48
48
|
import { useDispatch } from "react-redux";
|
|
49
|
+
import { useStableReference } from "../utils/hooks/useStableReference";
|
|
49
50
|
|
|
50
51
|
export { fieldRequired };
|
|
51
52
|
|
|
@@ -147,8 +148,8 @@ const AbstractInput = ({
|
|
|
147
148
|
noFillField,
|
|
148
149
|
noMarginBottom,
|
|
149
150
|
noOuterLabel,
|
|
150
|
-
onDefaultValChanged,
|
|
151
|
-
onFieldSubmit,
|
|
151
|
+
onDefaultValChanged: _onDefaultValChanged,
|
|
152
|
+
onFieldSubmit: _onFieldSubmit,
|
|
152
153
|
rightEl,
|
|
153
154
|
secondaryLabel,
|
|
154
155
|
setAssignDefaultsMode,
|
|
@@ -160,13 +161,16 @@ const AbstractInput = ({
|
|
|
160
161
|
tooltipProps
|
|
161
162
|
}) => {
|
|
162
163
|
const dispatch = useDispatch();
|
|
164
|
+
const onDefaultValChanged = useStableReference(_onDefaultValChanged);
|
|
165
|
+
const onFieldSubmit = useStableReference(_onFieldSubmit);
|
|
163
166
|
|
|
164
167
|
// This only takes care that the default Value is changed when it is changed in the parent component
|
|
165
168
|
useEffect(() => {
|
|
166
169
|
if (defaultValue !== undefined) {
|
|
167
170
|
dispatch(change(form, name, defaultValue));
|
|
168
|
-
onDefaultValChanged &&
|
|
169
|
-
|
|
171
|
+
onDefaultValChanged.current &&
|
|
172
|
+
onDefaultValChanged.current(defaultValue, name, form);
|
|
173
|
+
onFieldSubmit.current && onFieldSubmit.current(defaultValue);
|
|
170
174
|
}
|
|
171
175
|
}, [defaultValue, dispatch, form, name, onDefaultValChanged, onFieldSubmit]);
|
|
172
176
|
|
package/src/TgSelect/index.js
CHANGED
|
@@ -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
|
|
129
|
+
newValue = filter(value, obj => obj?.disabled) || [];
|
|
130
130
|
} else if (value && value.disabled) {
|
|
131
131
|
newValue = value;
|
|
132
132
|
}
|
package/src/UploadCsvWizard.js
CHANGED
|
@@ -11,7 +11,8 @@ import { some } from "lodash-es";
|
|
|
11
11
|
import { times } from "lodash-es";
|
|
12
12
|
import DialogFooter from "./DialogFooter";
|
|
13
13
|
import DataTable from "./DataTable";
|
|
14
|
-
import {
|
|
14
|
+
import { useDeepEqualMemo } from "./utils/hooks";
|
|
15
|
+
import { removeCleanRows } from "./DataTable/utils";
|
|
15
16
|
import wrapDialog from "./wrapDialog";
|
|
16
17
|
import { omit } from "lodash-es";
|
|
17
18
|
import { useDispatch, useSelector } from "react-redux";
|
package/src/index.js
CHANGED
|
@@ -22,7 +22,8 @@ export {
|
|
|
22
22
|
} from "./DataTable";
|
|
23
23
|
export { removeCleanRows, useTableEntities } from "./DataTable/utils";
|
|
24
24
|
|
|
25
|
-
export {
|
|
25
|
+
export { useDeepEqualMemo } from "./utils/hooks";
|
|
26
|
+
export { getIdOrCodeOrIndex } from "./DataTable/utils";
|
|
26
27
|
export { default as convertSchema } from "./DataTable/utils/convertSchema";
|
|
27
28
|
export { default as Loading } from "./Loading";
|
|
28
29
|
export { throwFormError } from "./throwFormError";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useDeepEqualMemo } from "./useDeepEqualMemo";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useDeepEqualMemo } from './useDeepEqualMemo';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function useDeepEqualMemo(value: any): undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function useStableReference(value: any): import('../../../../../node_modules/react').MutableRefObject<undefined>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export function withAbstractWrapper(ComponentToWrap: any, opts?: {}): (props: any) => import("react/jsx-runtime").JSX.Element;
|