authscape 1.0.374 → 1.0.376

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.
@@ -0,0 +1,852 @@
1
+ import React, {useCallback, useEffect, useRef, useState} from 'react';
2
+ import {createPortal, unstable_batchedUpdates} from 'react-dom';
3
+ import {
4
+ CancelDrop,
5
+ closestCenter,
6
+ pointerWithin,
7
+ rectIntersection,
8
+ CollisionDetection,
9
+ DndContext,
10
+ DragOverlay,
11
+ DropAnimation,
12
+ getFirstCollision,
13
+ KeyboardSensor,
14
+ MouseSensor,
15
+ TouchSensor,
16
+ Modifiers,
17
+ useDroppable,
18
+ UniqueIdentifier,
19
+ useSensors,
20
+ useSensor,
21
+ MeasuringStrategy,
22
+ KeyboardCoordinateGetter,
23
+ defaultDropAnimationSideEffects,
24
+ } from '@dnd-kit/core';
25
+ import {
26
+ AnimateLayoutChanges,
27
+ SortableContext,
28
+ useSortable,
29
+ arrayMove,
30
+ defaultAnimateLayoutChanges,
31
+ verticalListSortingStrategy,
32
+ SortingStrategy,
33
+ horizontalListSortingStrategy,
34
+ } from '@dnd-kit/sortable';
35
+ import {CSS} from '@dnd-kit/utilities';
36
+ import {coordinateGetter as multipleContainersCoordinateGetter} from './multipleContainersKeyboardCoordinates';
37
+ import { apiService } from 'authscape';
38
+
39
+ import { Item } from './item';
40
+ import { Container } from './container';
41
+ import { Box } from '@mui/material';
42
+
43
+ const animateLayoutChanges = (args) =>
44
+ defaultAnimateLayoutChanges({...args, wasDragging: true});
45
+
46
+ function DroppableContainer({
47
+ children,
48
+ columns = 1,
49
+ disabled,
50
+ id,
51
+ items,
52
+ style,
53
+ ...props
54
+ }) {
55
+ const {
56
+ active,
57
+ attributes,
58
+ isDragging,
59
+ listeners,
60
+ over,
61
+ setNodeRef,
62
+ transition,
63
+ transform,
64
+ } = useSortable({
65
+ id,
66
+ data: {
67
+ type: 'container',
68
+ children: items,
69
+ },
70
+ animateLayoutChanges,
71
+ });
72
+ const isOverContainer = over
73
+ ? (id === over.id && active?.data.current?.type !== 'container') ||
74
+ items.includes(over.id)
75
+ : false;
76
+
77
+ return (
78
+ <Container
79
+ ref={disabled ? undefined : setNodeRef}
80
+ style={{
81
+ ...style,
82
+ transition,
83
+ transform: CSS.Translate.toString(transform),
84
+ opacity: isDragging ? 0.5 : undefined,
85
+ }}
86
+ hover={isOverContainer}
87
+ handleProps={{
88
+ ...attributes,
89
+ ...listeners,
90
+ }}
91
+ columns={columns}
92
+ {...props}
93
+ >
94
+ {children}
95
+ </Container>
96
+ );
97
+ }
98
+
99
+ const dropAnimation = {
100
+ sideEffects: defaultDropAnimationSideEffects({
101
+ styles: {
102
+ active: {
103
+ opacity: '0.5',
104
+ },
105
+ },
106
+ }),
107
+ };
108
+
109
+ export const TRASH_ID = 'void';
110
+ const PLACEHOLDER_ID = 'placeholder';
111
+ const empty = [];
112
+
113
+ export function Kanban({
114
+ adjustScale = false,
115
+ itemCount = 3,
116
+ cancelDrop,
117
+ Menu = null,
118
+ columns,
119
+ loadedUser = true,
120
+ handle = false,
121
+ CardTemplate = null,
122
+ items: initialItems,
123
+ containerStyle,
124
+ coordinateGetter = multipleContainersCoordinateGetter,
125
+ getItemStyles = () => ({}),
126
+ wrapperStyle = () => ({}),
127
+ minimal = false,
128
+ modifiers,
129
+ renderItem,
130
+ strategy = verticalListSortingStrategy,
131
+ trashable = false,
132
+ vertical = false,
133
+ scrollable,
134
+ }) {
135
+
136
+ const [initItems, setInitItems] = useState(null);
137
+ const [cards, setCards] = useState(null);
138
+ const [items, setItems] = useState();
139
+ const [containers, setContainers] = useState();
140
+
141
+ useEffect(() => {
142
+
143
+ if (loadedUser)
144
+ {
145
+ const fetchData = async () => {
146
+
147
+ let response = await apiService().get("/Kanban/GetKanban");
148
+ if (response != null && response.status == 200)
149
+ {
150
+ let containers = [];
151
+ let initItems = response.data;
152
+ let cardNames = [];
153
+ let container = {};
154
+
155
+ initItems.forEach(element => {
156
+
157
+ containers.push(element.id);
158
+
159
+ let cards = [];
160
+ element.cards.forEach((card) => {
161
+ cards.push(card.id);
162
+ cardNames.push(card);
163
+ });
164
+
165
+ container[element.id] = cards;
166
+ });
167
+
168
+ setInitItems(initItems);
169
+ setCards(cardNames);
170
+ setItems(container);
171
+ setContainers(containers);
172
+ }
173
+ }
174
+ fetchData();
175
+ }
176
+
177
+ }, [loadedUser]);
178
+
179
+ const getContainerName = (containerId) => {
180
+
181
+ let name = "";
182
+ initItems.forEach(element => {
183
+ if (containerId == element.id)
184
+ {
185
+ name = element.name;
186
+ }
187
+ });
188
+
189
+ return name;
190
+ }
191
+
192
+ const getCardName = (cardId) => {
193
+
194
+ let name = "";
195
+ if (cards != null)
196
+ {
197
+ cards.forEach(card => {
198
+ if (cardId == card.id)
199
+ {
200
+ name = card.name;
201
+ }
202
+ });
203
+ }
204
+
205
+ return name;
206
+ }
207
+
208
+ const getCardDetails = (cardId) => {
209
+
210
+ let cardDetail = {};
211
+ if (cards != null)
212
+ {
213
+ cards.forEach(card => {
214
+ if (cardId == card.id)
215
+ {
216
+ cardDetail = card;
217
+ }
218
+ });
219
+ }
220
+
221
+ return cardDetail;
222
+ }
223
+
224
+
225
+ const [activeId, setActiveId] = useState(null);
226
+ const lastOverId = useRef(null);
227
+ const recentlyMovedToNewContainer = useRef(false);
228
+ const isSortingContainer = activeId ? containers.includes(activeId) : false;
229
+
230
+ /**
231
+ * Custom collision detection strategy optimized for multiple containers
232
+ *
233
+ * - First, find any droppable containers intersecting with the pointer.
234
+ * - If there are none, find intersecting containers with the active draggable.
235
+ * - If there are no intersecting containers, return the last matched intersection
236
+ *
237
+ */
238
+ const collisionDetectionStrategy = useCallback(
239
+ (args) => {
240
+ if (activeId && activeId in items) {
241
+ return closestCenter({
242
+ ...args,
243
+ droppableContainers: args.droppableContainers.filter(
244
+ (container) => container.id in items
245
+ ),
246
+ });
247
+ }
248
+
249
+ // Start by finding any intersecting droppable
250
+ const pointerIntersections = pointerWithin(args);
251
+ const intersections =
252
+ pointerIntersections.length > 0
253
+ ? // If there are droppables intersecting with the pointer, return those
254
+ pointerIntersections
255
+ : rectIntersection(args);
256
+ let overId = getFirstCollision(intersections, 'id');
257
+
258
+ if (overId != null) {
259
+ if (overId === TRASH_ID) {
260
+ // If the intersecting droppable is the trash, return early
261
+ // Remove this if you're not using trashable functionality in your app
262
+ return intersections;
263
+ }
264
+
265
+ if (overId in items) {
266
+ const containerItems = items[overId];
267
+
268
+ // If a container is matched and it contains items (columns 'A', 'B', 'C')
269
+ if (containerItems.length > 0) {
270
+ // Return the closest droppable within that container
271
+ overId = closestCenter({
272
+ ...args,
273
+ droppableContainers: args.droppableContainers.filter(
274
+ (container) =>
275
+ container.id !== overId &&
276
+ containerItems.includes(container.id)
277
+ ),
278
+ })[0]?.id;
279
+ }
280
+ }
281
+
282
+ lastOverId.current = overId;
283
+
284
+ return [{id: overId}];
285
+ }
286
+
287
+ // When a draggable item moves to a new container, the layout may shift
288
+ // and the `overId` may become `null`. We manually set the cached `lastOverId`
289
+ // to the id of the draggable item that was moved to the new container, otherwise
290
+ // the previous `overId` will be returned which can cause items to incorrectly shift positions
291
+ if (recentlyMovedToNewContainer.current) {
292
+ lastOverId.current = activeId;
293
+ }
294
+
295
+ // If no droppable is matched, return the last match
296
+ return lastOverId.current ? [{id: lastOverId.current}] : [];
297
+ },
298
+ [activeId, items]
299
+ );
300
+ const [clonedItems, setClonedItems] = useState(null);
301
+ const sensors = useSensors(
302
+ useSensor(MouseSensor, {
303
+ activationConstraint: { distance: 8 }
304
+ }),
305
+ useSensor(TouchSensor, {
306
+ activationConstraint: { distance: 8 }
307
+ }),
308
+ useSensor(KeyboardSensor, {
309
+ coordinateGetter,
310
+ activationConstraint: { distance: 8 }
311
+ })
312
+ );
313
+ const findContainer = (id) => {
314
+ if (id in items) {
315
+ return id;
316
+ }
317
+
318
+ return Object.keys(items).find((key) => items[key].includes(id));
319
+ };
320
+
321
+ const getIndex = (id) => {
322
+ const container = findContainer(id);
323
+
324
+ if (!container) {
325
+ return -1;
326
+ }
327
+
328
+ const index = items[container].indexOf(id);
329
+
330
+ return index;
331
+ };
332
+
333
+ const onDragCancel = () => {
334
+ if (clonedItems) {
335
+ // Reset items to their original state in case items have been
336
+ // Dragged across containers
337
+ setItems(clonedItems);
338
+ }
339
+
340
+ setActiveId(null);
341
+ setClonedItems(null);
342
+ };
343
+
344
+ useEffect(() => {
345
+ requestAnimationFrame(() => {
346
+ recentlyMovedToNewContainer.current = false;
347
+ });
348
+ }, [items]);
349
+
350
+
351
+ const [anchorEl, setAnchorEl] = useState(null);
352
+ const open = Boolean(anchorEl);
353
+ const handleMoreClick = (event) => {
354
+ setAnchorEl(event.currentTarget);
355
+ };
356
+ const handleMoreClose = () => {
357
+ setAnchorEl(null);
358
+ };
359
+
360
+ return (
361
+ <Box>
362
+ {(loadedUser && containers != null && cards != null && items != null) &&
363
+ <>
364
+ <DndContext
365
+ sensors={sensors}
366
+ collisionDetection={collisionDetectionStrategy}
367
+ measuring={{
368
+ droppable: {
369
+ strategy: MeasuringStrategy.Always,
370
+ },
371
+ }}
372
+ onDragStart={({active}) => {
373
+ setActiveId(active.id);
374
+ setClonedItems(items);
375
+ }}
376
+ onDragOver={({active, over}) => {
377
+ const overId = over?.id;
378
+
379
+ if (overId == null || overId === TRASH_ID || active.id in items) {
380
+ return;
381
+ }
382
+
383
+ const overContainer = findContainer(overId);
384
+ const activeContainer = findContainer(active.id);
385
+
386
+ if (!overContainer || !activeContainer) {
387
+ return;
388
+ }
389
+
390
+ if (activeContainer !== overContainer) {
391
+ setItems((items) => {
392
+ const activeItems = items[activeContainer];
393
+ const overItems = items[overContainer];
394
+ const overIndex = overItems.indexOf(overId);
395
+ const activeIndex = activeItems.indexOf(active.id);
396
+
397
+ let newIndex;
398
+
399
+ if (overId in items) {
400
+ newIndex = overItems.length + 1;
401
+ } else {
402
+ const isBelowOverItem =
403
+ over &&
404
+ active.rect.current.translated &&
405
+ active.rect.current.translated.top >
406
+ over.rect.top + over.rect.height;
407
+
408
+ const modifier = isBelowOverItem ? 1 : 0;
409
+
410
+ newIndex =
411
+ overIndex >= 0 ? overIndex + modifier : overItems.length + 1;
412
+ }
413
+
414
+ recentlyMovedToNewContainer.current = true;
415
+
416
+ return {
417
+ ...items,
418
+ [activeContainer]: items[activeContainer].filter(
419
+ (item) => item !== active.id
420
+ ),
421
+ [overContainer]: [
422
+ ...items[overContainer].slice(0, newIndex),
423
+ items[activeContainer][activeIndex],
424
+ ...items[overContainer].slice(
425
+ newIndex,
426
+ items[overContainer].length
427
+ ),
428
+ ],
429
+ };
430
+ });
431
+ }
432
+ }}
433
+ onDragEnd={({active, over}) => {
434
+ if (active.id in items && over?.id) {
435
+ setContainers((containers) => {
436
+ const activeIndex = containers.indexOf(active.id);
437
+ const overIndex = containers.indexOf(over.id);
438
+
439
+ let array = arrayMove(containers, activeIndex, overIndex);
440
+
441
+ apiService().put("/Kanban/SetColumnOrder", {
442
+ columnsIds: array
443
+ });
444
+
445
+ return array;
446
+ });
447
+ }
448
+
449
+ const activeContainer = findContainer(active.id);
450
+
451
+ if (!activeContainer) {
452
+ setActiveId(null);
453
+ return;
454
+ }
455
+
456
+ const overId = over?.id;
457
+
458
+ if (overId == null) {
459
+ setActiveId(null);
460
+ return;
461
+ }
462
+
463
+ if (overId === TRASH_ID) {
464
+ setItems((items) => ({
465
+ ...items,
466
+ [activeContainer]: items[activeContainer].filter(
467
+ (id) => id !== activeId
468
+ ),
469
+ }));
470
+ setActiveId(null);
471
+ return;
472
+ }
473
+
474
+ if (overId === PLACEHOLDER_ID) {
475
+ const newContainerId = getNextContainerId();
476
+
477
+ unstable_batchedUpdates(() => {
478
+ setContainers((containers) => [...containers, newContainerId]);
479
+ setItems((items) => ({
480
+ ...items,
481
+ [activeContainer]: items[activeContainer].filter(
482
+ (id) => id !== activeId
483
+ ),
484
+ [newContainerId]: [active.id],
485
+ }));
486
+ setActiveId(null);
487
+ });
488
+ return;
489
+ }
490
+
491
+ const overContainer = findContainer(overId);
492
+
493
+ if (overContainer) {
494
+
495
+ // you can't get the item from the key in an array, you need to search for it
496
+
497
+ var name = getContainerName(overContainer);
498
+
499
+ //alert(activeContainer + " \n" + overContainer)
500
+
501
+ const activeIndex = items[activeContainer].indexOf(active.id);
502
+ const overIndex = items[overContainer].indexOf(overId);
503
+
504
+ //alert(activeIndex + " - " + active.id + " !== " + overId + " - " + overIndex)
505
+
506
+
507
+
508
+ if (activeIndex !== overIndex) {
509
+
510
+ let newArray = arrayMove(
511
+ items[overContainer],
512
+ activeIndex,
513
+ overIndex
514
+ );
515
+
516
+ setItems((items) => ({
517
+ ...items,
518
+ [overContainer]: newArray,
519
+ }));
520
+
521
+ // get the items we need to rearrange
522
+ // alert(JSON.stringify(newArray))
523
+
524
+ apiService().put("/Kanban/AssignCardsBasedOnOrder", {
525
+ cardId: active.id,
526
+ columnId: overContainer,
527
+ cards: newArray
528
+ });
529
+
530
+ }
531
+ else
532
+ {
533
+ // assign the order of the cards
534
+ apiService().put("/Kanban/AssignColumnForCard", {
535
+ columnId: overContainer,
536
+ cardId: active.id,
537
+ orderId: 0
538
+ });
539
+ }
540
+ }
541
+
542
+ setActiveId(null);
543
+ }}
544
+ cancelDrop={cancelDrop}
545
+ onDragCancel={onDragCancel}
546
+ modifiers={modifiers}
547
+ >
548
+ <div
549
+ style={{
550
+ display: 'inline-grid',
551
+ boxSizing: 'border-box',
552
+ padding: 20,
553
+ gridAutoFlow: vertical ? 'row' : 'column',
554
+ }}
555
+ >
556
+ <SortableContext
557
+ items={[...containers, PLACEHOLDER_ID]}
558
+ strategy={
559
+ vertical
560
+ ? verticalListSortingStrategy
561
+ : horizontalListSortingStrategy
562
+ }
563
+ >
564
+ {containers.map((containerId) => {
565
+
566
+ let containerName = getContainerName(containerId);
567
+
568
+ return (
569
+ <DroppableContainer
570
+ key={containerId}
571
+ id={containerId}
572
+ label={containerName}
573
+ columns={columns}
574
+ items={items[containerId]}
575
+ scrollable={scrollable}
576
+ style={containerStyle}
577
+ unstyled={minimal}
578
+ onRemove={() => handleRemove(containerId)}
579
+ >
580
+ <SortableContext items={items[containerId]} strategy={strategy}>
581
+ {items[containerId].map((value, index) => {
582
+
583
+ return (
584
+ <SortableItem
585
+ disabled={isSortingContainer}
586
+ key={value}
587
+ id={value}
588
+ cardDetail={getCardDetails(value)}
589
+ CardTemplate={CardTemplate}
590
+ handleMoreClick={handleMoreClick}
591
+ handleMoreClose={handleMoreClose}
592
+ name={getCardName(value)}
593
+ index={index}
594
+ handle={handle}
595
+ style={getItemStyles}
596
+ wrapperStyle={wrapperStyle}
597
+ renderItem={renderItem}
598
+ containerId={containerId}
599
+ getIndex={getIndex}
600
+ />
601
+ );
602
+ })}
603
+ </SortableContext>
604
+ </DroppableContainer>
605
+ )})}
606
+ {minimal ? undefined : (
607
+ <DroppableContainer
608
+ id={PLACEHOLDER_ID}
609
+ disabled={isSortingContainer}
610
+ items={empty}
611
+ onClick={handleAddColumn}
612
+ placeholder
613
+ >
614
+ + Add column
615
+ </DroppableContainer>
616
+ )}
617
+ </SortableContext>
618
+
619
+
620
+
621
+ </div>
622
+ {createPortal(
623
+ <DragOverlay adjustScale={adjustScale} dropAnimation={dropAnimation}>
624
+ {activeId
625
+ ? containers.includes(activeId)
626
+ ? renderContainerDragOverlay(CardTemplate, activeId)
627
+ : renderSortableItemDragOverlay(CardTemplate, activeId)
628
+ : null}
629
+ </DragOverlay>,
630
+ document.body
631
+ )}
632
+ {trashable && activeId && !containers.includes(activeId) ? (
633
+ <Trash id={TRASH_ID} />
634
+ ) : null}
635
+ </DndContext>
636
+ {Menu != null &&
637
+ <Menu anchorEl={anchorEl} open={open} handleMoreClose={handleMoreClose} />
638
+ }
639
+ </>
640
+ }
641
+ </Box>
642
+ );
643
+
644
+ function renderSortableItemDragOverlay(CardTemplate, id) {
645
+ return (
646
+ <Item
647
+ value={id}
648
+ name={getCardName(id)}
649
+ cardDetail={getCardDetails(id)}
650
+ CardTemplate={CardTemplate}
651
+ handle={handle}
652
+ style={getItemStyles({
653
+ containerId: findContainer(id),
654
+ overIndex: -1,
655
+ index: getIndex(id),
656
+ value: id,
657
+ isSorting: true,
658
+ isDragging: true,
659
+ isDragOverlay: true,
660
+ })}
661
+ color={getColor(id)}
662
+ wrapperStyle={wrapperStyle({index: 0})}
663
+ renderItem={renderItem}
664
+ dragOverlay
665
+ />
666
+ );
667
+ }
668
+
669
+ function renderContainerDragOverlay(CardTemplate, containerId) {
670
+ return (
671
+ <Container
672
+ label={getContainerName(containerId)}
673
+ columns={columns}
674
+ style={{
675
+ height: '100%',
676
+ paddingRight:"10px"
677
+ }}
678
+ shadow
679
+ unstyled={false}
680
+ >
681
+ {items[containerId].map((item, index) => (
682
+ <Item
683
+ key={item}
684
+ value={item}
685
+ CardTemplate={CardTemplate}
686
+ cardDetail={getCardDetails(item)}
687
+ name={getCardName(item)}
688
+ handle={handle}
689
+ style={getItemStyles({
690
+ containerId,
691
+ overIndex: -1,
692
+ index: getIndex(item),
693
+ value: item,
694
+ isDragging: false,
695
+ isSorting: false,
696
+ isDragOverlay: false,
697
+ })}
698
+ color={getColor(item)}
699
+ wrapperStyle={wrapperStyle({index})}
700
+ renderItem={renderItem}
701
+ />
702
+ ))}
703
+ </Container>
704
+ );
705
+ }
706
+
707
+ function handleRemove(containerID) {
708
+ setContainers((containers) =>
709
+ containers.filter((id) => id !== containerID)
710
+ );
711
+ }
712
+
713
+ function handleAddColumn() {
714
+ const newContainerId = getNextContainerId();
715
+
716
+ unstable_batchedUpdates(() => {
717
+ setContainers((containers) => [...containers, newContainerId]);
718
+ setItems((items) => ({
719
+ ...items,
720
+ [newContainerId]: [],
721
+ }));
722
+ });
723
+ }
724
+
725
+ function getNextContainerId() {
726
+ const containerIds = Object.keys(items);
727
+ const lastContainerId = containerIds[containerIds.length - 1];
728
+
729
+ return String.fromCharCode(lastContainerId.charCodeAt(0) + 1);
730
+ }
731
+ }
732
+
733
+
734
+ function getColor(id) {
735
+ switch (String(id)[0]) {
736
+ case 'A':
737
+ return '#7193f1';
738
+ case 'B':
739
+ return '#ffda6c';
740
+ case 'C':
741
+ return '#00bcd4';
742
+ case 'D':
743
+ return '#ef769f';
744
+ }
745
+
746
+ return undefined;
747
+ }
748
+
749
+ function Trash({id}) {
750
+ const {setNodeRef, isOver} = useDroppable({
751
+ id,
752
+ });
753
+
754
+ return (
755
+ <div
756
+ ref={setNodeRef}
757
+ style={{
758
+ display: 'flex',
759
+ alignItems: 'center',
760
+ justifyContent: 'center',
761
+ position: 'fixed',
762
+ left: '50%',
763
+ marginLeft: -150,
764
+ bottom: 20,
765
+ width: 300,
766
+ height: 60,
767
+ borderRadius: 5,
768
+ border: '1px solid',
769
+ borderColor: isOver ? 'red' : '#DDD',
770
+ }}
771
+ >
772
+ Drop here to delete
773
+ </div>
774
+ );
775
+ }
776
+
777
+ function SortableItem({
778
+ disabled,
779
+ id,
780
+ index,
781
+ handle,
782
+ name,
783
+ renderItem,
784
+ CardTemplate,
785
+ cardDetail,
786
+ handleMoreClick,
787
+ handleMoreClose,
788
+ style,
789
+ containerId,
790
+ getIndex,
791
+ wrapperStyle,
792
+ }) {
793
+ const {
794
+ setNodeRef,
795
+ setActivatorNodeRef,
796
+ listeners,
797
+ isDragging,
798
+ isSorting,
799
+ over,
800
+ overIndex,
801
+ transform,
802
+ transition,
803
+ } = useSortable({
804
+ id,
805
+ });
806
+ const mounted = useMountStatus();
807
+ const mountedWhileDragging = isDragging && !mounted;
808
+
809
+ return (
810
+ <Item
811
+ ref={disabled ? undefined : setNodeRef}
812
+ value={id}
813
+ dragging={isDragging}
814
+ sorting={isSorting}
815
+ cardDetail={cardDetail}
816
+ CardTemplate={CardTemplate}
817
+ handleMoreClick={handleMoreClick}
818
+ handleMoreClose={handleMoreClose}
819
+ name={name}
820
+ handle={handle}
821
+ handleProps={handle ? {ref: setActivatorNodeRef} : undefined}
822
+ index={index}
823
+ wrapperStyle={wrapperStyle({index})}
824
+ style={style({
825
+ index,
826
+ value: id,
827
+ isDragging,
828
+ isSorting,
829
+ overIndex: over ? getIndex(over.id) : overIndex,
830
+ containerId,
831
+ })}
832
+ color={getColor(id)}
833
+ transition={transition}
834
+ transform={transform}
835
+ fadeIn={mountedWhileDragging}
836
+ listeners={listeners}
837
+ renderItem={renderItem}
838
+ />
839
+ );
840
+ }
841
+
842
+ function useMountStatus() {
843
+ const [isMounted, setIsMounted] = useState(false);
844
+
845
+ useEffect(() => {
846
+ const timeout = setTimeout(() => setIsMounted(true), 500);
847
+
848
+ return () => clearTimeout(timeout);
849
+ }, []);
850
+
851
+ return isMounted;
852
+ }