feat: enhance CSV upload handling with chunked requests and token support; improve form input limits

This commit is contained in:
2025-08-14 10:38:35 +02:00
parent bb63388986
commit 214a3cb3c8
6 changed files with 961 additions and 61 deletions

View File

@@ -1,3 +1,852 @@
test1
test12
test123
100000
100001
100002
100003
100004
100005
100006
100007
100008
100009
100010
100011
100012
100013
100014
100015
100016
100017
100018
100019
100020
100021
100022
100023
100024
100025
100026
100027
100028
100029
100030
100031
100032
100033
100034
100035
100036
100037
100038
100039
100040
100041
100042
100043
100044
100045
100046
100047
100048
100049
100050
100051
100052
100053
100054
100055
100056
100057
100058
100059
100060
100061
100062
100063
100064
100065
100066
100067
100068
100069
100070
100071
100072
100073
100074
100075
100076
100077
100078
100079
100080
100081
100082
100083
100084
100085
100086
100087
100088
100089
100090
100091
100092
100093
100094
100095
100096
100097
100098
100099
100100
100101
100102
100103
100104
100105
100106
100107
100108
100109
100110
100111
100112
100113
100114
100115
100116
100117
100118
100119
100120
100121
100122
100123
100124
100125
100126
100127
100128
100129
100130
100131
100132
100133
100134
100135
100136
100137
100138
100139
100140
100141
100142
100143
100144
100145
100146
100147
100148
100149
100150
100151
100152
100153
100154
100155
100156
100157
100158
100159
100160
100161
100162
100163
100164
100165
100166
100167
100168
100169
100170
100171
100172
100173
100174
100175
100176
100177
100178
100179
100180
100181
100182
100183
100184
100185
100186
100187
100188
100189
100190
100191
100192
100193
100194
100195
100196
100197
100198
100199
100200
100201
100202
100203
100204
100205
100206
100207
100208
100209
100210
100211
100212
100213
100214
100215
100216
100217
100218
100219
100220
100221
100222
100223
100224
100225
100226
100227
100228
100229
100230
100231
100232
100233
100234
100235
100236
100237
100238
100239
100240
100241
100242
100243
100244
100245
100246
100247
100248
100249
100250
100251
100252
100253
100254
100255
100256
100257
100258
100259
100260
100261
100262
100263
100264
100265
100266
100267
100268
100269
100270
100271
100272
100273
100274
100275
100276
100277
100278
100279
100280
100281
100282
100283
100284
100285
100286
100287
100288
100289
100290
100291
100292
100293
100294
100295
100296
100297
100298
100299
100300
100301
100302
100303
100304
100305
100306
100307
100308
100309
100310
100311
100312
100313
100314
100315
100316
100317
100318
100319
100320
100321
100322
100323
100324
100325
100326
100327
100328
100329
100330
100331
100332
100333
100334
100335
100336
100337
100338
100339
100340
100341
100342
100343
100344
100345
100346
100347
100348
100349
100350
100351
100352
100353
100354
100355
100356
100357
100358
100359
100360
100361
100362
100363
100364
100365
100366
100367
100368
100369
100370
100371
100372
100373
100374
100375
100376
100377
100378
100379
100380
100381
100382
100383
100384
100385
100386
100387
100388
100389
100390
100391
100392
100393
100394
100395
100396
100397
100398
100399
100400
100401
100402
100403
100404
100405
100406
100407
100408
100409
100410
100411
100412
100413
100414
100415
100416
100417
100418
100419
100420
100421
100422
100423
100424
100425
100426
100427
100428
100429
100430
100431
100432
100433
100434
100435
100436
100437
100438
100439
100440
100441
100442
100443
100444
100445
100446
100447
100448
100449
100450
100451
100452
100453
100454
100455
100456
100457
100458
100459
100460
100461
100462
100463
100464
100465
100466
100467
100468
100469
100470
100471
100472
100473
100474
100475
100476
100477
100478
100479
100480
100481
100482
100483
100484
100485
100486
100487
100488
100489
100490
100491
100492
100493
100494
100495
100496
100497
100498
100499
100500
100501
100502
100503
100504
100505
100506
100507
100508
100509
100510
100511
100512
100513
100514
100515
100516
100517
100518
100519
100520
100521
100522
100523
100524
100525
100526
100527
100528
100529
100530
100531
100532
100533
100534
100535
100536
100537
100538
100539
100540
100541
100542
100543
100544
100545
100546
100547
100548
100549
100550
100551
100552
100553
100554
100555
100556
100557
100558
100559
100560
100561
100562
100563
100564
100565
100566
100567
100568
100569
100570
100571
100572
100573
100574
100575
100576
100577
100578
100579
100580
100581
100582
100583
100584
100585
100586
100587
100588
100589
100590
100591
100592
100593
100594
100595
100596
100597
100598
100599
100600
100601
100602
100603
100604
100605
100606
100607
100608
100609
100610
100611
100612
100613
100614
100615
100616
100617
100618
100619
100620
100621
100622
100623
100624
100625
100626
100627
100628
100629
100630
100631
100632
100633
100634
100635
100636
100637
100638
100639
100640
100641
100642
100643
100644
100645
100646
100647
100648
100649
100650
100651
100652
100653
100654
100655
100656
100657
100658
100659
100660
100661
100662
100663
100664
100665
100666
100667
100668
100669
100670
100671
100672
100673
100674
100675
100676
100677
100678
100679
100680
100681
100682
100683
100684
100685
100686
100687
100688
100689
100690
100691
100692
100693
100694
100695
100696
100697
100698
100699
100700
100701
100702
100703
100704
100705
100706
100707
100708
100709
100710
100711
100712
100713
100714
100715
100716
100717
100718
100719
100720
100721
100722
100723
100724
100725
100726
100727
100728
100729
100730
100731
100732
100733
100734
100735
100736
100737
100738
100739
100740
100741
100742
100743
100744
100745
100746
100747
100748
100749
100750
100751
100752
100753
100754
100755
100756
100757
100758
100759
100760
100761
100762
100763
100764
100765
100766
100767
100768
100769
100770
100771
100772
100773
100774
100775
100776
100777
100778
100779
100780
100781
100782
100783
100784
100785
100786
100787
100788
100789
100790
100791
100792
100793
100794
100795
100796
100797
100798
100799
100800
100801
100802
100803
100804
100805
100806
100807
100808
100809
100810
100811
100812
100813
100814
100815
100816
100817
100818
100819
100820
100821
100822
100823
100824
100825
100826
100827
100828
100829
100830
100831
100832
100833
100834
100835
100836
100837
100838
100839
100840
100841
100842
100843
100844
100845
100846
100847
100848
100849
100850
100851
1 test1 100000
2 test12 100001
3 test123 100002
4 100003
5 100004
6 100005
7 100006
8 100007
9 100008
10 100009
11 100010
12 100011
13 100012
14 100013
15 100014
16 100015
17 100016
18 100017
19 100018
20 100019
21 100020
22 100021
23 100022
24 100023
25 100024
26 100025
27 100026
28 100027
29 100028
30 100029
31 100030
32 100031
33 100032
34 100033
35 100034
36 100035
37 100036
38 100037
39 100038
40 100039
41 100040
42 100041
43 100042
44 100043
45 100044
46 100045
47 100046
48 100047
49 100048
50 100049
51 100050
52 100051
53 100052
54 100053
55 100054
56 100055
57 100056
58 100057
59 100058
60 100059
61 100060
62 100061
63 100062
64 100063
65 100064
66 100065
67 100066
68 100067
69 100068
70 100069
71 100070
72 100071
73 100072
74 100073
75 100074
76 100075
77 100076
78 100077
79 100078
80 100079
81 100080
82 100081
83 100082
84 100083
85 100084
86 100085
87 100086
88 100087
89 100088
90 100089
91 100090
92 100091
93 100092
94 100093
95 100094
96 100095
97 100096
98 100097
99 100098
100 100099
101 100100
102 100101
103 100102
104 100103
105 100104
106 100105
107 100106
108 100107
109 100108
110 100109
111 100110
112 100111
113 100112
114 100113
115 100114
116 100115
117 100116
118 100117
119 100118
120 100119
121 100120
122 100121
123 100122
124 100123
125 100124
126 100125
127 100126
128 100127
129 100128
130 100129
131 100130
132 100131
133 100132
134 100133
135 100134
136 100135
137 100136
138 100137
139 100138
140 100139
141 100140
142 100141
143 100142
144 100143
145 100144
146 100145
147 100146
148 100147
149 100148
150 100149
151 100150
152 100151
153 100152
154 100153
155 100154
156 100155
157 100156
158 100157
159 100158
160 100159
161 100160
162 100161
163 100162
164 100163
165 100164
166 100165
167 100166
168 100167
169 100168
170 100169
171 100170
172 100171
173 100172
174 100173
175 100174
176 100175
177 100176
178 100177
179 100178
180 100179
181 100180
182 100181
183 100182
184 100183
185 100184
186 100185
187 100186
188 100187
189 100188
190 100189
191 100190
192 100191
193 100192
194 100193
195 100194
196 100195
197 100196
198 100197
199 100198
200 100199
201 100200
202 100201
203 100202
204 100203
205 100204
206 100205
207 100206
208 100207
209 100208
210 100209
211 100210
212 100211
213 100212
214 100213
215 100214
216 100215
217 100216
218 100217
219 100218
220 100219
221 100220
222 100221
223 100222
224 100223
225 100224
226 100225
227 100226
228 100227
229 100228
230 100229
231 100230
232 100231
233 100232
234 100233
235 100234
236 100235
237 100236
238 100237
239 100238
240 100239
241 100240
242 100241
243 100242
244 100243
245 100244
246 100245
247 100246
248 100247
249 100248
250 100249
251 100250
252 100251
253 100252
254 100253
255 100254
256 100255
257 100256
258 100257
259 100258
260 100259
261 100260
262 100261
263 100262
264 100263
265 100264
266 100265
267 100266
268 100267
269 100268
270 100269
271 100270
272 100271
273 100272
274 100273
275 100274
276 100275
277 100276
278 100277
279 100278
280 100279
281 100280
282 100281
283 100282
284 100283
285 100284
286 100285
287 100286
288 100287
289 100288
290 100289
291 100290
292 100291
293 100292
294 100293
295 100294
296 100295
297 100296
298 100297
299 100298
300 100299
301 100300
302 100301
303 100302
304 100303
305 100304
306 100305
307 100306
308 100307
309 100308
310 100309
311 100310
312 100311
313 100312
314 100313
315 100314
316 100315
317 100316
318 100317
319 100318
320 100319
321 100320
322 100321
323 100322
324 100323
325 100324
326 100325
327 100326
328 100327
329 100328
330 100329
331 100330
332 100331
333 100332
334 100333
335 100334
336 100335
337 100336
338 100337
339 100338
340 100339
341 100340
342 100341
343 100342
344 100343
345 100344
346 100345
347 100346
348 100347
349 100348
350 100349
351 100350
352 100351
353 100352
354 100353
355 100354
356 100355
357 100356
358 100357
359 100358
360 100359
361 100360
362 100361
363 100362
364 100363
365 100364
366 100365
367 100366
368 100367
369 100368
370 100369
371 100370
372 100371
373 100372
374 100373
375 100374
376 100375
377 100376
378 100377
379 100378
380 100379
381 100380
382 100381
383 100382
384 100383
385 100384
386 100385
387 100386
388 100387
389 100388
390 100389
391 100390
392 100391
393 100392
394 100393
395 100394
396 100395
397 100396
398 100397
399 100398
400 100399
401 100400
402 100401
403 100402
404 100403
405 100404
406 100405
407 100406
408 100407
409 100408
410 100409
411 100410
412 100411
413 100412
414 100413
415 100414
416 100415
417 100416
418 100417
419 100418
420 100419
421 100420
422 100421
423 100422
424 100423
425 100424
426 100425
427 100426
428 100427
429 100428
430 100429
431 100430
432 100431
433 100432
434 100433
435 100434
436 100435
437 100436
438 100437
439 100438
440 100439
441 100440
442 100441
443 100442
444 100443
445 100444
446 100445
447 100446
448 100447
449 100448
450 100449
451 100450
452 100451
453 100452
454 100453
455 100454
456 100455
457 100456
458 100457
459 100458
460 100459
461 100460
462 100461
463 100462
464 100463
465 100464
466 100465
467 100466
468 100467
469 100468
470 100469
471 100470
472 100471
473 100472
474 100473
475 100474
476 100475
477 100476
478 100477
479 100478
480 100479
481 100480
482 100481
483 100482
484 100483
485 100484
486 100485
487 100486
488 100487
489 100488
490 100489
491 100490
492 100491
493 100492
494 100493
495 100494
496 100495
497 100496
498 100497
499 100498
500 100499
501 100500
502 100501
503 100502
504 100503
505 100504
506 100505
507 100506
508 100507
509 100508
510 100509
511 100510
512 100511
513 100512
514 100513
515 100514
516 100515
517 100516
518 100517
519 100518
520 100519
521 100520
522 100521
523 100522
524 100523
525 100524
526 100525
527 100526
528 100527
529 100528
530 100529
531 100530
532 100531
533 100532
534 100533
535 100534
536 100535
537 100536
538 100537
539 100538
540 100539
541 100540
542 100541
543 100542
544 100543
545 100544
546 100545
547 100546
548 100547
549 100548
550 100549
551 100550
552 100551
553 100552
554 100553
555 100554
556 100555
557 100556
558 100557
559 100558
560 100559
561 100560
562 100561
563 100562
564 100563
565 100564
566 100565
567 100566
568 100567
569 100568
570 100569
571 100570
572 100571
573 100572
574 100573
575 100574
576 100575
577 100576
578 100577
579 100578
580 100579
581 100580
582 100581
583 100582
584 100583
585 100584
586 100585
587 100586
588 100587
589 100588
590 100589
591 100590
592 100591
593 100592
594 100593
595 100594
596 100595
597 100596
598 100597
599 100598
600 100599
601 100600
602 100601
603 100602
604 100603
605 100604
606 100605
607 100606
608 100607
609 100608
610 100609
611 100610
612 100611
613 100612
614 100613
615 100614
616 100615
617 100616
618 100617
619 100618
620 100619
621 100620
622 100621
623 100622
624 100623
625 100624
626 100625
627 100626
628 100627
629 100628
630 100629
631 100630
632 100631
633 100632
634 100633
635 100634
636 100635
637 100636
638 100637
639 100638
640 100639
641 100640
642 100641
643 100642
644 100643
645 100644
646 100645
647 100646
648 100647
649 100648
650 100649
651 100650
652 100651
653 100652
654 100653
655 100654
656 100655
657 100656
658 100657
659 100658
660 100659
661 100660
662 100661
663 100662
664 100663
665 100664
666 100665
667 100666
668 100667
669 100668
670 100669
671 100670
672 100671
673 100672
674 100673
675 100674
676 100675
677 100676
678 100677
679 100678
680 100679
681 100680
682 100681
683 100682
684 100683
685 100684
686 100685
687 100686
688 100687
689 100688
690 100689
691 100690
692 100691
693 100692
694 100693
695 100694
696 100695
697 100696
698 100697
699 100698
700 100699
701 100700
702 100701
703 100702
704 100703
705 100704
706 100705
707 100706
708 100707
709 100708
710 100709
711 100710
712 100711
713 100712
714 100713
715 100714
716 100715
717 100716
718 100717
719 100718
720 100719
721 100720
722 100721
723 100722
724 100723
725 100724
726 100725
727 100726
728 100727
729 100728
730 100729
731 100730
732 100731
733 100732
734 100733
735 100734
736 100735
737 100736
738 100737
739 100738
740 100739
741 100740
742 100741
743 100742
744 100743
745 100744
746 100745
747 100746
748 100747
749 100748
750 100749
751 100750
752 100751
753 100752
754 100753
755 100754
756 100755
757 100756
758 100757
759 100758
760 100759
761 100760
762 100761
763 100762
764 100763
765 100764
766 100765
767 100766
768 100767
769 100768
770 100769
771 100770
772 100771
773 100772
774 100773
775 100774
776 100775
777 100776
778 100777
779 100778
780 100779
781 100780
782 100781
783 100782
784 100783
785 100784
786 100785
787 100786
788 100787
789 100788
790 100789
791 100790
792 100791
793 100792
794 100793
795 100794
796 100795
797 100796
798 100797
799 100798
800 100799
801 100800
802 100801
803 100802
804 100803
805 100804
806 100805
807 100806
808 100807
809 100808
810 100809
811 100810
812 100811
813 100812
814 100813
815 100814
816 100815
817 100816
818 100817
819 100818
820 100819
821 100820
822 100821
823 100822
824 100823
825 100824
826 100825
827 100826
828 100827
829 100828
830 100829
831 100830
832 100831
833 100832
834 100833
835 100834
836 100835
837 100836
838 100837
839 100838
840 100839
841 100840
842 100841
843 100842
844 100843
845 100844
846 100845
847 100846
848 100847
849 100848
850 100849
851 100850
852 100851

View File

@@ -1,5 +1,5 @@
import React from "react";
import { Sheet, WholeWord } from "lucide-react";
import { Sheet, WholeWord, Search } from "lucide-react";
import { useState } from "react";
import ImportGUI from "./ImportGUI";
import { removeSelection } from "../utils/tableActions";
@@ -7,10 +7,17 @@ import { removeSelection } from "../utils/tableActions";
type SubHeaderAdminProps = {
setFiles: (files: File[]) => void;
files?: File[];
search: string;
setSearch: (value: string) => void;
};
// Sub navigation bar for admin views: provides import + clear selection actions
const SubHeaderAdmin: React.FC<SubHeaderAdminProps> = ({ setFiles, files }) => {
const SubHeaderAdmin: React.FC<SubHeaderAdminProps> = ({
setFiles,
files,
search,
setSearch,
}) => {
const [showImport, setShowImport] = useState(false);
return (
@@ -30,6 +37,17 @@ const SubHeaderAdmin: React.FC<SubHeaderAdminProps> = ({ setFiles, files }) => {
</p>
</div>
<div className="flex items-center gap-2">
{/* Search */}
<div className="relative hidden sm:block">
<Search className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" />
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Suchen… (Losnummer, Name, Adresse, PLZ, Email)"
className="w-72 rounded-md border border-gray-300 bg-white pl-9 pr-3 py-2 text-sm text-gray-900 placeholder-gray-400 shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
</div>
<button
onClick={() => setShowImport(true)}
type="button"

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useEffect, useMemo, useState } from "react";
import Cookies from "js-cookie";
import { useQuery } from "@tanstack/react-query";
import { getTableData, readCachedTableData } from "../utils/userHandler";
@@ -19,6 +19,7 @@ interface DataPackage {
const Table: React.FC = () => {
const [rows, setRows] = useState<DataPackage[]>([]); // holds normalized cache view
const [files, setFiles] = useState<File[]>([]);
const [search, setSearch] = useState("");
// Einheitliche Input-Styles (nur Tailwind)
const inputClasses =
@@ -81,9 +82,33 @@ const Table: React.FC = () => {
);
};
// Filter rows by search query (case-insensitive)
const filteredRows = useMemo(() => {
const q = search.trim().toLowerCase();
if (!q) return rows;
return rows.filter((r) => {
const values = [
r.losnummer,
r.vorname ?? "",
r.nachname ?? "",
r.adresse ?? "",
r.plz ?? "",
r.email ?? "",
]
.join(" ")
.toLowerCase();
return values.includes(q);
});
}, [rows, search]);
return (
<>
<SubHeaderAdmin setFiles={setFiles} files={files} />
<SubHeaderAdmin
setFiles={setFiles}
files={files}
search={search}
setSearch={setSearch}
/>
<div className="w-full">
{/*
<div className="mb-4 flex items-center gap-3">
@@ -156,7 +181,7 @@ const Table: React.FC = () => {
</tr>
</thead>
<tbody className="divide-y divide-gray-100 bg-white">
{rows.length === 0 && !tableQuery.isLoading && (
{filteredRows.length === 0 && !tableQuery.isLoading && (
<tr>
<td
colSpan={8}
@@ -166,7 +191,7 @@ const Table: React.FC = () => {
</td>
</tr>
)}
{rows.map((row, idx) => (
{filteredRows.map((row, idx) => (
<tr
key={row.losnummer ?? idx}
className="hover:bg-gray-50 transition-colors"

View File

@@ -46,21 +46,31 @@ export async function postCSV(file: File): Promise<boolean> {
reader.readAsText(file, "utf-8");
});
const res = await fetch("http://localhost:8002/create-entry", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
losnummer: await readerLines,
}),
});
const lines = await readerLines;
if (res.ok) {
myToast("CSV Datei erfolgreich importiert!", "success");
queryClient.invalidateQueries({ queryKey: ["table-data"] });
return true;
// Send token if available
const token = (await import("js-cookie")).default.get("token");
// Chunk uploads to avoid huge single payloads
const chunkSize = 2000; // ~2k per request => 25 requests for 50k
for (let i = 0; i < lines.length; i += chunkSize) {
const chunk = lines.slice(i, i + chunkSize);
const res = await fetch("http://localhost:8002/create-entry", {
method: "POST",
headers: {
"Content-Type": "application/json",
...(token ? { Authorization: `Bearer ${token}` } : {}),
},
body: JSON.stringify({ losnummer: chunk }),
});
if (!res.ok) {
myToast(`Fehler beim Importieren (Batch ${i / chunkSize + 1}).`, "error");
return false;
}
}
myToast("Fehler beim Importieren der CSV Datei.", "error");
return false;
myToast("CSV Datei erfolgreich importiert!", "success");
queryClient.invalidateQueries({ queryKey: ["table-data"] });
return true;
}