@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.
- package/README.md +55 -0
- package/package.json +1 -1
- package/src/components/crm/AssociationManager.jsx +431 -0
- package/src/components/crm/BusinessCardOcr.jsx +190 -6
- package/src/components/crm/ClientAssociationManager.jsx +362 -0
- package/src/components/crm/MergeEntity.jsx +1049 -0
- package/src/components/crm/MultiSelect.jsx +14 -3
- package/src/components/crm/Navigation.jsx +67 -8
- package/src/components/crm/cells/CellWithTooltip.jsx +35 -28
- package/src/components/crm/generic/GenericDetail.jsx +25 -0
- package/src/components/crm/generic/GenericReport.jsx +1457 -434
- package/src/components/crm/generic/styles/GenericReport.module.scss +598 -24
- package/src/components/crm/styles/AssociationManager.module.scss +364 -0
- package/src/components/crm/styles/BusinessCardOcr.module.scss +362 -94
- package/src/components/crm/styles/ClientAssociationManager.module.scss +290 -0
- package/src/components/crm/styles/MergeEntity.module.scss +690 -0
- package/src/components/crm/styles/MultiSelect.module.scss +18 -0
- package/src/components/crm/styles/Navigation.module.scss +148 -16
- package/src/components/crm/styles/global-datagrid.css +9 -0
- package/src/index.js +6 -0
|
@@ -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}>
|
|
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
|
|
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={
|
|
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
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
}
|