@visns-studio/visns-components 5.13.3 → 5.13.4
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/package.json
CHANGED
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
88
88
|
},
|
|
89
89
|
"name": "@visns-studio/visns-components",
|
|
90
|
-
"version": "5.13.
|
|
90
|
+
"version": "5.13.4",
|
|
91
91
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
92
92
|
"main": "src/index.js",
|
|
93
93
|
"files": [
|
|
@@ -17,6 +17,7 @@ const CategorizedDropZone = ({
|
|
|
17
17
|
entityData = {},
|
|
18
18
|
routeParams = {},
|
|
19
19
|
fetchData = null,
|
|
20
|
+
showDescription = true,
|
|
20
21
|
}) => {
|
|
21
22
|
useEffect(() => {
|
|
22
23
|
// Initialize component
|
|
@@ -118,33 +119,17 @@ const CategorizedDropZone = ({
|
|
|
118
119
|
console.log('CategorizedDropZone: Processing files', currentFiles);
|
|
119
120
|
|
|
120
121
|
currentFiles.forEach((file) => {
|
|
121
|
-
console.log('CategorizedDropZone: Processing file', {
|
|
122
|
-
file_name: file.file_name,
|
|
123
|
-
file_description: file.file_description,
|
|
124
|
-
id: file.id,
|
|
125
|
-
});
|
|
126
|
-
|
|
127
122
|
const category = getCategoryFromDescription(
|
|
128
123
|
file.file_description
|
|
129
124
|
);
|
|
130
|
-
console.log(
|
|
131
|
-
'CategorizedDropZone: Category extracted',
|
|
132
|
-
category
|
|
133
|
-
);
|
|
134
125
|
|
|
135
126
|
if (category && initialCategorizedFiles[category]) {
|
|
136
127
|
initialCategorizedFiles[category].push(file);
|
|
137
|
-
console.log(
|
|
138
|
-
`CategorizedDropZone: Added file ${file.file_name} to category ${category}`
|
|
139
|
-
);
|
|
140
128
|
} else {
|
|
141
129
|
// For uncategorized files, add them to the first available category as fallback
|
|
142
130
|
if (finalCategories.length > 0) {
|
|
143
131
|
const firstCategory = finalCategories[0].id;
|
|
144
132
|
initialCategorizedFiles[firstCategory].push(file);
|
|
145
|
-
console.log(
|
|
146
|
-
`CategorizedDropZone: Added uncategorized file ${file.file_name} to first category ${firstCategory}`
|
|
147
|
-
);
|
|
148
133
|
} else {
|
|
149
134
|
console.log(
|
|
150
135
|
`CategorizedDropZone: No category match for file ${file.file_name}`,
|
|
@@ -160,10 +145,6 @@ const CategorizedDropZone = ({
|
|
|
160
145
|
});
|
|
161
146
|
}
|
|
162
147
|
|
|
163
|
-
console.log(
|
|
164
|
-
'CategorizedDropZone: Final categorized files',
|
|
165
|
-
initialCategorizedFiles
|
|
166
|
-
);
|
|
167
148
|
setCategorizedFiles(initialCategorizedFiles);
|
|
168
149
|
}, [entityData, dataKey, finalCategories]);
|
|
169
150
|
|
|
@@ -329,6 +310,7 @@ const CategorizedDropZone = ({
|
|
|
329
310
|
folder: folder,
|
|
330
311
|
filetype: filetype,
|
|
331
312
|
deleteUrl: deleteUrl,
|
|
313
|
+
showDescription: showDescription,
|
|
332
314
|
}}
|
|
333
315
|
/>
|
|
334
316
|
</div>
|
|
@@ -399,6 +381,7 @@ const CategorizedDropZone = ({
|
|
|
399
381
|
},
|
|
400
382
|
model:
|
|
401
383
|
entityData?.constructor?.name || 'Design',
|
|
384
|
+
showDescription: showDescription,
|
|
402
385
|
}}
|
|
403
386
|
/>
|
|
404
387
|
</div>
|
|
@@ -24,7 +24,7 @@ const truncateText = (text, maxLength) => {
|
|
|
24
24
|
|
|
25
25
|
// Sortable gallery item
|
|
26
26
|
const SortableGalleryItem = SortableElement(
|
|
27
|
-
({ value, handleEdit, handleDelete }) => {
|
|
27
|
+
({ value, handleEdit, handleDelete, showDescription = true }) => {
|
|
28
28
|
const imageUrl = value.image_url || value.file_url;
|
|
29
29
|
const title =
|
|
30
30
|
value.file_title || value.label || value.file_name || 'Untitled';
|
|
@@ -49,7 +49,7 @@ const SortableGalleryItem = SortableElement(
|
|
|
49
49
|
<h3 className={styles.galleryTitle}>
|
|
50
50
|
{truncateText(title, 30)}
|
|
51
51
|
</h3>
|
|
52
|
-
{description && (
|
|
52
|
+
{showDescription && description && (
|
|
53
53
|
<p className={styles.galleryDescription}>
|
|
54
54
|
{truncateText(description, 100)}
|
|
55
55
|
</p>
|
|
@@ -94,7 +94,7 @@ const SortableGalleryItem = SortableElement(
|
|
|
94
94
|
);
|
|
95
95
|
|
|
96
96
|
// Sortable gallery container
|
|
97
|
-
const Gallery = SortableContainer(({ items, handleEdit, handleDelete }) => {
|
|
97
|
+
const Gallery = SortableContainer(({ items, handleEdit, handleDelete, showDescription = true }) => {
|
|
98
98
|
if (!items || items.length === 0) {
|
|
99
99
|
return (
|
|
100
100
|
<div className={styles.galleryEmpty}>
|
|
@@ -138,6 +138,7 @@ const Gallery = SortableContainer(({ items, handleEdit, handleDelete }) => {
|
|
|
138
138
|
value={value}
|
|
139
139
|
handleEdit={handleEdit}
|
|
140
140
|
handleDelete={handleDelete}
|
|
141
|
+
showDescription={showDescription}
|
|
141
142
|
/>
|
|
142
143
|
))}
|
|
143
144
|
</div>
|
|
@@ -449,16 +449,358 @@ export const renderImageColumn = ({ column, commonProps }) => {
|
|
|
449
449
|
name: column.id,
|
|
450
450
|
render: ({ data }) => {
|
|
451
451
|
if (data && data[column.id]) {
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
452
|
+
const imageData = data[column.id];
|
|
453
|
+
|
|
454
|
+
// Handle both array and single object cases
|
|
455
|
+
const imageArray = Array.isArray(imageData) ? imageData : [imageData];
|
|
456
|
+
|
|
457
|
+
// Filter out items without file_url
|
|
458
|
+
const validImages = imageArray.filter(item => item && item.file_url);
|
|
459
|
+
|
|
460
|
+
if (validImages.length === 0) {
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Function to handle image click
|
|
465
|
+
const handleImageClick = (initialImageUrl, event) => {
|
|
466
|
+
event.stopPropagation(); // Prevent edit modal from opening
|
|
467
|
+
|
|
468
|
+
let currentImageIndex = validImages.findIndex(img => img.file_url === initialImageUrl);
|
|
469
|
+
|
|
470
|
+
// Create a modal backdrop
|
|
471
|
+
const modalBackdrop = document.createElement('div');
|
|
472
|
+
modalBackdrop.style.cssText = `
|
|
473
|
+
position: fixed;
|
|
474
|
+
top: 0;
|
|
475
|
+
left: 0;
|
|
476
|
+
width: 100%;
|
|
477
|
+
height: 100%;
|
|
478
|
+
background-color: rgba(0, 0, 0, 0.8);
|
|
479
|
+
display: flex;
|
|
480
|
+
justify-content: center;
|
|
481
|
+
align-items: center;
|
|
482
|
+
z-index: 9999;
|
|
483
|
+
cursor: pointer;
|
|
484
|
+
`;
|
|
485
|
+
|
|
486
|
+
// Create modal container
|
|
487
|
+
const modalContainer = document.createElement('div');
|
|
488
|
+
modalContainer.style.cssText = `
|
|
489
|
+
position: relative;
|
|
490
|
+
max-width: 90vw;
|
|
491
|
+
max-height: 90vh;
|
|
492
|
+
display: flex;
|
|
493
|
+
flex-direction: column;
|
|
494
|
+
align-items: center;
|
|
495
|
+
cursor: default;
|
|
496
|
+
`;
|
|
497
|
+
|
|
498
|
+
// Create close button
|
|
499
|
+
const closeButton = document.createElement('button');
|
|
500
|
+
closeButton.innerHTML = '×';
|
|
501
|
+
closeButton.style.cssText = `
|
|
502
|
+
position: absolute;
|
|
503
|
+
top: -40px;
|
|
504
|
+
right: 0;
|
|
505
|
+
background: rgba(255, 255, 255, 0.9);
|
|
506
|
+
border: none;
|
|
507
|
+
border-radius: 50%;
|
|
508
|
+
width: 35px;
|
|
509
|
+
height: 35px;
|
|
510
|
+
font-size: 24px;
|
|
511
|
+
font-weight: bold;
|
|
512
|
+
color: #333;
|
|
513
|
+
cursor: pointer;
|
|
514
|
+
display: flex;
|
|
515
|
+
align-items: center;
|
|
516
|
+
justify-content: center;
|
|
517
|
+
z-index: 10001;
|
|
518
|
+
transition: all 0.2s ease;
|
|
519
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
|
|
520
|
+
`;
|
|
521
|
+
|
|
522
|
+
// Create enlarged image
|
|
523
|
+
const enlargedImage = document.createElement('img');
|
|
524
|
+
enlargedImage.src = initialImageUrl;
|
|
525
|
+
enlargedImage.style.cssText = `
|
|
526
|
+
max-width: 100%;
|
|
527
|
+
max-height: 100%;
|
|
528
|
+
border-radius: 8px;
|
|
529
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
|
530
|
+
object-fit: contain;
|
|
531
|
+
`;
|
|
532
|
+
|
|
533
|
+
// Create navigation controls (only if multiple images)
|
|
534
|
+
let prevButton, nextButton, imageCounter;
|
|
535
|
+
if (validImages.length > 1) {
|
|
536
|
+
// Previous button
|
|
537
|
+
prevButton = document.createElement('button');
|
|
538
|
+
prevButton.innerHTML = '‹';
|
|
539
|
+
prevButton.style.cssText = `
|
|
540
|
+
position: absolute;
|
|
541
|
+
left: -50px;
|
|
542
|
+
top: 50%;
|
|
543
|
+
transform: translateY(-50%);
|
|
544
|
+
background: rgba(255, 255, 255, 0.9);
|
|
545
|
+
border: none;
|
|
546
|
+
border-radius: 50%;
|
|
547
|
+
width: 40px;
|
|
548
|
+
height: 40px;
|
|
549
|
+
font-size: 24px;
|
|
550
|
+
font-weight: bold;
|
|
551
|
+
color: #333;
|
|
552
|
+
cursor: pointer;
|
|
553
|
+
display: flex;
|
|
554
|
+
align-items: center;
|
|
555
|
+
justify-content: center;
|
|
556
|
+
z-index: 10001;
|
|
557
|
+
transition: all 0.2s ease;
|
|
558
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
|
|
559
|
+
`;
|
|
560
|
+
|
|
561
|
+
// Next button
|
|
562
|
+
nextButton = document.createElement('button');
|
|
563
|
+
nextButton.innerHTML = '›';
|
|
564
|
+
nextButton.style.cssText = `
|
|
565
|
+
position: absolute;
|
|
566
|
+
right: -50px;
|
|
567
|
+
top: 50%;
|
|
568
|
+
transform: translateY(-50%);
|
|
569
|
+
background: rgba(255, 255, 255, 0.9);
|
|
570
|
+
border: none;
|
|
571
|
+
border-radius: 50%;
|
|
572
|
+
width: 40px;
|
|
573
|
+
height: 40px;
|
|
574
|
+
font-size: 24px;
|
|
575
|
+
font-weight: bold;
|
|
576
|
+
color: #333;
|
|
577
|
+
cursor: pointer;
|
|
578
|
+
display: flex;
|
|
579
|
+
align-items: center;
|
|
580
|
+
justify-content: center;
|
|
581
|
+
z-index: 10001;
|
|
582
|
+
transition: all 0.2s ease;
|
|
583
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
|
|
584
|
+
`;
|
|
585
|
+
|
|
586
|
+
// Image counter
|
|
587
|
+
imageCounter = document.createElement('div');
|
|
588
|
+
imageCounter.style.cssText = `
|
|
589
|
+
position: absolute;
|
|
590
|
+
bottom: -40px;
|
|
591
|
+
left: 50%;
|
|
592
|
+
transform: translateX(-50%);
|
|
593
|
+
background: rgba(255, 255, 255, 0.9);
|
|
594
|
+
padding: 8px 16px;
|
|
595
|
+
border-radius: 20px;
|
|
596
|
+
font-size: 14px;
|
|
597
|
+
color: #333;
|
|
598
|
+
font-weight: 500;
|
|
599
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
|
|
600
|
+
`;
|
|
601
|
+
|
|
602
|
+
// Update image counter
|
|
603
|
+
const updateCounter = () => {
|
|
604
|
+
imageCounter.textContent = `${currentImageIndex + 1} / ${validImages.length}`;
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
updateCounter();
|
|
608
|
+
|
|
609
|
+
// Navigation functions
|
|
610
|
+
const updateImage = () => {
|
|
611
|
+
enlargedImage.src = validImages[currentImageIndex].file_url;
|
|
612
|
+
updateCounter();
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
const goToPrevious = () => {
|
|
616
|
+
currentImageIndex = (currentImageIndex - 1 + validImages.length) % validImages.length;
|
|
617
|
+
updateImage();
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
const goToNext = () => {
|
|
621
|
+
currentImageIndex = (currentImageIndex + 1) % validImages.length;
|
|
622
|
+
updateImage();
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
// Add event listeners
|
|
626
|
+
prevButton.addEventListener('click', goToPrevious);
|
|
627
|
+
nextButton.addEventListener('click', goToNext);
|
|
628
|
+
|
|
629
|
+
// Add buttons to container
|
|
630
|
+
modalContainer.appendChild(prevButton);
|
|
631
|
+
modalContainer.appendChild(nextButton);
|
|
632
|
+
modalContainer.appendChild(imageCounter);
|
|
633
|
+
|
|
634
|
+
// Keyboard navigation
|
|
635
|
+
const handleKeyDown = (e) => {
|
|
636
|
+
if (e.key === 'ArrowLeft') {
|
|
637
|
+
goToPrevious();
|
|
638
|
+
} else if (e.key === 'ArrowRight') {
|
|
639
|
+
goToNext();
|
|
640
|
+
} else if (e.key === 'Escape') {
|
|
641
|
+
closeModal();
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
645
|
+
|
|
646
|
+
// Store cleanup function
|
|
647
|
+
modalBackdrop.keydownHandler = handleKeyDown;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Close modal function
|
|
651
|
+
const closeModal = () => {
|
|
652
|
+
document.body.removeChild(modalBackdrop);
|
|
653
|
+
if (modalBackdrop.keydownHandler) {
|
|
654
|
+
document.removeEventListener('keydown', modalBackdrop.keydownHandler);
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
|
|
658
|
+
// Close button event
|
|
659
|
+
closeButton.addEventListener('click', closeModal);
|
|
660
|
+
|
|
661
|
+
// Close modal when clicking backdrop
|
|
662
|
+
modalBackdrop.addEventListener('click', (e) => {
|
|
663
|
+
if (e.target === modalBackdrop) {
|
|
664
|
+
closeModal();
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
// Close modal on escape key (for single image)
|
|
669
|
+
if (validImages.length === 1) {
|
|
670
|
+
const handleKeyDown = (e) => {
|
|
671
|
+
if (e.key === 'Escape') {
|
|
672
|
+
closeModal();
|
|
673
|
+
}
|
|
674
|
+
};
|
|
675
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
676
|
+
modalBackdrop.keydownHandler = handleKeyDown;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// Add hover effects
|
|
680
|
+
const addHoverEffects = (button) => {
|
|
681
|
+
button.addEventListener('mouseenter', () => {
|
|
682
|
+
button.style.background = 'rgba(255, 255, 255, 1)';
|
|
683
|
+
button.style.transform = button.style.transform.replace('translateY(-50%)', 'translateY(-50%) scale(1.1)');
|
|
684
|
+
});
|
|
685
|
+
button.addEventListener('mouseleave', () => {
|
|
686
|
+
button.style.background = 'rgba(255, 255, 255, 0.9)';
|
|
687
|
+
button.style.transform = button.style.transform.replace('scale(1.1)', '');
|
|
688
|
+
});
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
addHoverEffects(closeButton);
|
|
692
|
+
if (prevButton) addHoverEffects(prevButton);
|
|
693
|
+
if (nextButton) addHoverEffects(nextButton);
|
|
694
|
+
|
|
695
|
+
// Assemble modal
|
|
696
|
+
modalContainer.appendChild(closeButton);
|
|
697
|
+
modalContainer.appendChild(enlargedImage);
|
|
698
|
+
modalBackdrop.appendChild(modalContainer);
|
|
699
|
+
document.body.appendChild(modalBackdrop);
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
// If single image, display it as thumbnail
|
|
703
|
+
if (validImages.length === 1) {
|
|
456
704
|
return (
|
|
457
|
-
<
|
|
458
|
-
|
|
459
|
-
|
|
705
|
+
<div
|
|
706
|
+
style={{
|
|
707
|
+
position: 'relative',
|
|
708
|
+
display: 'inline-block',
|
|
709
|
+
borderRadius: '4px',
|
|
710
|
+
overflow: 'hidden',
|
|
711
|
+
cursor: 'pointer',
|
|
712
|
+
transition: 'all 0.2s ease'
|
|
713
|
+
}}
|
|
714
|
+
onClick={(event) => handleImageClick(validImages[0].file_url, event)}
|
|
715
|
+
onMouseEnter={(e) => {
|
|
716
|
+
e.target.style.transform = 'scale(1.05)';
|
|
717
|
+
e.target.style.boxShadow = '0 4px 15px rgba(0, 0, 0, 0.2)';
|
|
718
|
+
}}
|
|
719
|
+
onMouseLeave={(e) => {
|
|
720
|
+
e.target.style.transform = 'scale(1)';
|
|
721
|
+
e.target.style.boxShadow = '0 1px 3px rgba(0, 0, 0, 0.1)';
|
|
722
|
+
}}
|
|
723
|
+
>
|
|
724
|
+
<img
|
|
725
|
+
src={validImages[0].file_url}
|
|
726
|
+
alt="Click to enlarge"
|
|
727
|
+
style={{
|
|
728
|
+
width: '50px',
|
|
729
|
+
height: '50px',
|
|
730
|
+
objectFit: 'cover',
|
|
731
|
+
borderRadius: '4px',
|
|
732
|
+
border: '1px solid #ddd',
|
|
733
|
+
display: 'block'
|
|
734
|
+
}}
|
|
735
|
+
/>
|
|
736
|
+
</div>
|
|
460
737
|
);
|
|
461
738
|
}
|
|
739
|
+
|
|
740
|
+
// If multiple images, display them in a grid
|
|
741
|
+
return (
|
|
742
|
+
<div style={{
|
|
743
|
+
display: 'grid',
|
|
744
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(40px, 1fr))',
|
|
745
|
+
gap: '2px',
|
|
746
|
+
maxWidth: '120px'
|
|
747
|
+
}}>
|
|
748
|
+
{validImages.map((image, index) => (
|
|
749
|
+
<div
|
|
750
|
+
key={index}
|
|
751
|
+
style={{
|
|
752
|
+
position: 'relative',
|
|
753
|
+
display: 'inline-block',
|
|
754
|
+
borderRadius: '4px',
|
|
755
|
+
overflow: 'hidden',
|
|
756
|
+
cursor: 'pointer',
|
|
757
|
+
transition: 'all 0.2s ease'
|
|
758
|
+
}}
|
|
759
|
+
onClick={(event) => handleImageClick(image.file_url, event)}
|
|
760
|
+
onMouseEnter={(e) => {
|
|
761
|
+
e.currentTarget.style.transform = 'scale(1.1)';
|
|
762
|
+
e.currentTarget.style.boxShadow = '0 4px 15px rgba(0, 0, 0, 0.2)';
|
|
763
|
+
e.currentTarget.style.zIndex = '10';
|
|
764
|
+
}}
|
|
765
|
+
onMouseLeave={(e) => {
|
|
766
|
+
e.currentTarget.style.transform = 'scale(1)';
|
|
767
|
+
e.currentTarget.style.boxShadow = '0 1px 3px rgba(0, 0, 0, 0.1)';
|
|
768
|
+
e.currentTarget.style.zIndex = '1';
|
|
769
|
+
}}
|
|
770
|
+
>
|
|
771
|
+
<img
|
|
772
|
+
src={image.file_url}
|
|
773
|
+
alt={`Click to enlarge (${index + 1}/${validImages.length})`}
|
|
774
|
+
style={{
|
|
775
|
+
width: '40px',
|
|
776
|
+
height: '40px',
|
|
777
|
+
objectFit: 'cover',
|
|
778
|
+
borderRadius: '4px',
|
|
779
|
+
border: '1px solid #ddd',
|
|
780
|
+
display: 'block'
|
|
781
|
+
}}
|
|
782
|
+
/>
|
|
783
|
+
{index === 0 && validImages.length > 1 && (
|
|
784
|
+
<div
|
|
785
|
+
style={{
|
|
786
|
+
position: 'absolute',
|
|
787
|
+
bottom: '1px',
|
|
788
|
+
left: '1px',
|
|
789
|
+
background: 'rgba(0, 0, 0, 0.7)',
|
|
790
|
+
color: 'white',
|
|
791
|
+
borderRadius: '8px',
|
|
792
|
+
padding: '1px 4px',
|
|
793
|
+
fontSize: '8px',
|
|
794
|
+
fontWeight: 'bold'
|
|
795
|
+
}}
|
|
796
|
+
>
|
|
797
|
+
+{validImages.length - 1}
|
|
798
|
+
</div>
|
|
799
|
+
)}
|
|
800
|
+
</div>
|
|
801
|
+
))}
|
|
802
|
+
</div>
|
|
803
|
+
);
|
|
462
804
|
}
|
|
463
805
|
|
|
464
806
|
return null;
|
|
@@ -2857,13 +2857,28 @@ function GenericDetail({
|
|
|
2857
2857
|
return null;
|
|
2858
2858
|
}
|
|
2859
2859
|
case 'categorized_dropzone':
|
|
2860
|
-
// Replace URL parameters like {
|
|
2860
|
+
// Replace URL parameters like {key} with actual values
|
|
2861
2861
|
const replaceUrlParams = (url) => {
|
|
2862
2862
|
if (!url) return url;
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2863
|
+
|
|
2864
|
+
// Handle the new urlKey parameter
|
|
2865
|
+
const urlKey = activeTabConfig.urlKey || 'dataId';
|
|
2866
|
+
|
|
2867
|
+
let replacementValue;
|
|
2868
|
+
if (urlKey === 'dataId') {
|
|
2869
|
+
// Use routeParams for dataId (backward compatibility)
|
|
2870
|
+
replacementValue = routeParams[urlParam] || '';
|
|
2871
|
+
} else {
|
|
2872
|
+
// Use data object for other keys, supporting dot notation
|
|
2873
|
+
replacementValue = urlKey.split('.').reduce((obj, key) => {
|
|
2874
|
+
return obj && obj[key] !== undefined ? obj[key] : '';
|
|
2875
|
+
}, data);
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
// Replace both {key} and {dataId} patterns for backward compatibility
|
|
2879
|
+
return url
|
|
2880
|
+
.replace(/{key}/g, replacementValue)
|
|
2881
|
+
.replace(/{dataId}/g, replacementValue);
|
|
2867
2882
|
};
|
|
2868
2883
|
|
|
2869
2884
|
return (
|
|
@@ -2891,6 +2906,7 @@ function GenericDetail({
|
|
|
2891
2906
|
entityData={data}
|
|
2892
2907
|
routeParams={routeParams}
|
|
2893
2908
|
fetchData={handleReload}
|
|
2909
|
+
showDescription={activeTabConfig.showDescription}
|
|
2894
2910
|
/>
|
|
2895
2911
|
);
|
|
2896
2912
|
case 'scheduling':
|