authscape 1.0.388 → 1.0.392

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