@visns-studio/visns-components 5.11.2 → 5.11.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.
@@ -36,16 +36,27 @@ const CustomOption = (props) => {
36
36
 
37
37
  // Custom MultiValue component to display description for selected values
38
38
  const CustomMultiValue = (props) => {
39
- const { children, data, ...rest } = props;
39
+ const { children, data, removeProps, settings, ...rest } = props;
40
+
40
41
  return (
41
42
  <components.MultiValue {...rest}>
42
43
  <div className={styles.multiValue}>
43
- <div className={styles.multiValueLabel}>{children}</div>
44
+ <div className={styles.multiValueLabel}>
45
+ {children}
46
+ {data.is_primary && settings?.primaryField && (
47
+ <span className={styles.primaryIndicator}>Primary</span>
48
+ )}
49
+ </div>
44
50
  {data.description && (
45
51
  <div className={styles.multiValueDescription}>
46
52
  {data.description}
47
53
  </div>
48
54
  )}
55
+ {data.relationship_type && settings?.relationshipTypes && (
56
+ <div className={styles.relationshipType}>
57
+ {data.relationship_type}
58
+ </div>
59
+ )}
49
60
  </div>
50
61
  </components.MultiValue>
51
62
  );
@@ -218,7 +229,7 @@ function MultiSelect({
218
229
  components={{
219
230
  SelectList,
220
231
  Option: CustomOption,
221
- MultiValue: CustomMultiValue,
232
+ MultiValue: (props) => <CustomMultiValue {...props} settings={settings} />,
222
233
  }}
223
234
  options={selectOptions}
224
235
  menuPortalTarget={document.body}
@@ -183,6 +183,7 @@ function Navigation({
183
183
  setSystemAuth,
184
184
  themeType,
185
185
  userProfile,
186
+ debugIcons = false, // Add debug flag
186
187
  }) {
187
188
  const [search, setSearch] = useState('');
188
189
  const [searchResultShow, setSearchResultShow] = useState(false);
@@ -197,6 +198,7 @@ function Navigation({
197
198
  const [isScrolled, setIsScrolled] = useState(false);
198
199
  const [navData, setNavData] = useState(navConfig);
199
200
  const [showBusinessCardOcr, setShowBusinessCardOcr] = useState(false);
201
+ const actionItemsRef = useRef(null);
200
202
 
201
203
  const appNavClasses = styles['app-nav'];
202
204
 
@@ -289,15 +291,14 @@ function Navigation({
289
291
  const IconComponent = iconComponents[n.icon];
290
292
 
291
293
  return (
292
- <li className={activeClass}>
293
- {' '}
294
- {/* Apply active class to the list item */}
294
+ <li>
295
295
  <Link
296
296
  to={n.url}
297
297
  data-tooltip-id="system-tooltip"
298
298
  data-tooltip-content={n.label}
299
- className={`tooltip ${activeClass}`} // Apply active class to the link
299
+ className={`${activeClass}`}
300
300
  target={n.target ? n.target : '_self'}
301
+ title={n.label}
301
302
  >
302
303
  <IconComponent size={19} strokeWidth={2} />
303
304
  </Link>
@@ -533,13 +534,65 @@ function Navigation({
533
534
  useEffect(() => {
534
535
  function handleScroll() {
535
536
  setIsScrolled(window.scrollY > 0);
537
+
538
+ // Debug logging for icon visibility
539
+ if (debugIcons && actionItemsRef.current) {
540
+ const anchors = actionItemsRef.current.querySelectorAll('a');
541
+ const buttons =
542
+ actionItemsRef.current.querySelectorAll('button');
543
+
544
+ console.log('=== SCROLL DEBUG ===');
545
+ console.log('Scroll Y:', window.scrollY);
546
+ console.log('Anchors found:', anchors.length);
547
+ console.log('Buttons found:', buttons.length);
548
+
549
+ anchors.forEach((anchor, index) => {
550
+ const rect = anchor.getBoundingClientRect();
551
+ const computedStyle = window.getComputedStyle(anchor);
552
+ console.log(`Anchor ${index}:`, {
553
+ visible: rect.width > 0 && rect.height > 0,
554
+ position: {
555
+ top: rect.top,
556
+ left: rect.left,
557
+ width: rect.width,
558
+ height: rect.height,
559
+ },
560
+ zIndex: computedStyle.zIndex,
561
+ display: computedStyle.display,
562
+ visibility: computedStyle.visibility,
563
+ opacity: computedStyle.opacity,
564
+ transform: computedStyle.transform,
565
+ contain: computedStyle.contain,
566
+ });
567
+ });
568
+
569
+ buttons.forEach((button, index) => {
570
+ const rect = button.getBoundingClientRect();
571
+ const computedStyle = window.getComputedStyle(button);
572
+ console.log(`Button ${index}:`, {
573
+ visible: rect.width > 0 && rect.height > 0,
574
+ position: {
575
+ top: rect.top,
576
+ left: rect.left,
577
+ width: rect.width,
578
+ height: rect.height,
579
+ },
580
+ zIndex: computedStyle.zIndex,
581
+ display: computedStyle.display,
582
+ visibility: computedStyle.visibility,
583
+ opacity: computedStyle.opacity,
584
+ transform: computedStyle.transform,
585
+ contain: computedStyle.contain,
586
+ });
587
+ });
588
+ }
536
589
  }
537
590
 
538
591
  window.addEventListener('scroll', handleScroll);
539
592
  return () => {
540
593
  window.removeEventListener('scroll', handleScroll);
541
594
  };
542
- }, []);
595
+ }, [debugIcons]);
543
596
 
544
597
  return layout === 'simple' || layout === 'cms' ? (
545
598
  <div className={styles.cwrap}>
@@ -602,7 +655,12 @@ function Navigation({
602
655
  <span></span>
603
656
  </button>
604
657
  </div>
605
- <div className={styles['hactions-alternate']}>
658
+ <div
659
+ className={`${styles['hactions-alternate']} ${
660
+ debugIcons ? styles['debug-icons'] : ''
661
+ }`}
662
+ ref={actionItemsRef}
663
+ >
606
664
  <ul>
607
665
  {navData.settings.map((setting, settingKey) =>
608
666
  setting.permission === true ? (
@@ -654,11 +712,12 @@ function Navigation({
654
712
  </ul>
655
713
  </div>
656
714
  <div
657
- className={
715
+ className={`${
658
716
  themeType === 'alternate'
659
717
  ? styles['hactions-alternate']
660
718
  : styles.hactions
661
- }
719
+ } ${debugIcons ? styles['debug-icons'] : ''}`}
720
+ ref={actionItemsRef}
662
721
  >
663
722
  <ul>
664
723
  {navData.settings.map((setting, settingKey) =>
@@ -1,4 +1,5 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
+ import { createPortal } from 'react-dom';
2
3
  import { Tooltip } from 'react-tooltip';
3
4
  import moment from 'moment';
4
5
  import numeral from 'numeral';
@@ -103,35 +104,41 @@ const CellWithTooltip = ({
103
104
  width: '100%',
104
105
  };
105
106
 
107
+ // Render tooltip using createPortal to escape stacking contexts
108
+ const tooltipPortal = shouldShowTooltip && createPortal(
109
+ <Tooltip
110
+ id={tooltipId}
111
+ style={{
112
+ backgroundColor: 'rgba(0, 0, 0, 0.9)',
113
+ color: 'white',
114
+ borderRadius: '6px',
115
+ padding: '8px 12px',
116
+ fontSize: '13px',
117
+ maxWidth: '500px',
118
+ wordWrap: 'break-word',
119
+ zIndex: 9999, // Slightly lower since we're now at document.body level
120
+ }}
121
+ place="top"
122
+ offset={5}
123
+ />,
124
+ document.body
125
+ );
126
+
106
127
  return (
107
- <div
108
- ref={cellRef}
109
- className={className}
110
- style={cellStyles}
111
- {...(shouldShowTooltip && {
112
- 'data-tooltip-id': tooltipId,
113
- 'data-tooltip-html': tooltipContent,
114
- })}
115
- >
116
- {children}
117
- {shouldShowTooltip && (
118
- <Tooltip
119
- id={tooltipId}
120
- style={{
121
- backgroundColor: 'rgba(0, 0, 0, 0.9)',
122
- color: 'white',
123
- borderRadius: '6px',
124
- padding: '8px 12px',
125
- fontSize: '13px',
126
- maxWidth: '500px',
127
- wordWrap: 'break-word',
128
- zIndex: 1000,
129
- }}
130
- place="top"
131
- offset={5}
132
- />
133
- )}
134
- </div>
128
+ <>
129
+ <div
130
+ ref={cellRef}
131
+ className={className}
132
+ style={cellStyles}
133
+ {...(shouldShowTooltip && {
134
+ 'data-tooltip-id': tooltipId,
135
+ 'data-tooltip-html': tooltipContent,
136
+ })}
137
+ >
138
+ {children}
139
+ </div>
140
+ {tooltipPortal}
141
+ </>
135
142
  );
136
143
  };
137
144
 
@@ -63,10 +63,12 @@ import 'react-big-calendar/lib/css/react-big-calendar.css';
63
63
  import 'react-big-calendar/lib/addons/dragAndDrop/styles.css';
64
64
 
65
65
  import Breadcrumb from '../Breadcrumb';
66
+ import AssociationManager from '../AssociationManager';
66
67
  import CustomFetch from '../Fetch';
67
68
  import Form from '../Form';
68
69
  import GenericDynamic from './GenericDynamic';
69
70
  import GenericEditableTable from './GenericEditableTable';
71
+ import MergeEntity from '../MergeEntity';
70
72
  import MultiSelect from '../MultiSelect';
71
73
  import QrCode from '../QrCode';
72
74
  import Table from '../DataGrid';
@@ -2490,6 +2492,29 @@ function GenericDetail({
2490
2492
  setData={setData}
2491
2493
  />
2492
2494
  );
2495
+ case 'custom':
2496
+ // Handle custom components
2497
+ if (activeTabConfig.component === 'AssociationManager' || activeTabConfig.component === 'ClientAssociationManager') {
2498
+ return (
2499
+ <AssociationManager
2500
+ endpoints={activeTabConfig.endpoints}
2501
+ config={activeTabConfig.config}
2502
+ dataId={routeParams[urlParam]}
2503
+ onUpdate={handleReload}
2504
+ />
2505
+ );
2506
+ }
2507
+ if (activeTabConfig.component === 'MergeEntity') {
2508
+ return (
2509
+ <MergeEntity
2510
+ endpoints={activeTabConfig.endpoints}
2511
+ config={activeTabConfig.config}
2512
+ dataId={routeParams[urlParam]}
2513
+ onUpdate={handleReload}
2514
+ />
2515
+ );
2516
+ }
2517
+ return null;
2493
2518
  default:
2494
2519
  return null;
2495
2520
  }