@eric-emg/symphiq-components 1.2.45 → 1.2.46
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.
|
@@ -21632,27 +21632,23 @@ class SymphiqFunnelAnalysisDashboardComponent {
|
|
|
21632
21632
|
// Manage overall assessment loading state during view mode transitions
|
|
21633
21633
|
}
|
|
21634
21634
|
ngAfterViewInit() {
|
|
21635
|
-
console.log('[DASHBOARD
|
|
21636
|
-
embedded: this.embedded(),
|
|
21637
|
-
scrollContainerId: this.scrollContainerId(),
|
|
21638
|
-
isScrolled: this.isScrolled(),
|
|
21639
|
-
viewMode: this.viewMode()
|
|
21640
|
-
});
|
|
21635
|
+
console.log('[DASHBOARD v6] ngAfterViewInit - event-driven scroll approach');
|
|
21641
21636
|
// Ensure modal has data after view is initialized
|
|
21642
21637
|
if (this.modalComponent) {
|
|
21643
21638
|
this.modalComponent.setMetricsAndInsights(this.allMetrics(), this.insights(), this.allCharts());
|
|
21644
21639
|
}
|
|
21645
|
-
//
|
|
21640
|
+
// v6 - Pure event-driven scroll detection
|
|
21641
|
+
// No initial state checking, no timeouts, no ResizeObserver
|
|
21642
|
+
// Header state only updates on actual scroll events
|
|
21646
21643
|
if (this.embedded()) {
|
|
21647
21644
|
let container = null;
|
|
21648
|
-
// If a scroll container ID is provided, use that element
|
|
21649
21645
|
if (this.scrollContainerId()) {
|
|
21650
21646
|
const setupScrollContainer = () => {
|
|
21651
21647
|
const element = document.getElementById(this.scrollContainerId());
|
|
21652
|
-
console.log('[SCROLL
|
|
21648
|
+
console.log('[SCROLL v6] Setup attempt', {
|
|
21653
21649
|
scrollContainerId: this.scrollContainerId(),
|
|
21654
|
-
|
|
21655
|
-
|
|
21650
|
+
found: !!element,
|
|
21651
|
+
tag: element?.tagName
|
|
21656
21652
|
});
|
|
21657
21653
|
if (!element) {
|
|
21658
21654
|
return false;
|
|
@@ -21660,248 +21656,42 @@ class SymphiqFunnelAnalysisDashboardComponent {
|
|
|
21660
21656
|
// Check if this is an Ionic ion-content element
|
|
21661
21657
|
if (element.tagName.toLowerCase() === 'ion-content') {
|
|
21662
21658
|
const ionContent = element;
|
|
21663
|
-
// Get the scrollable element from Ionic
|
|
21664
21659
|
if (typeof ionContent.getScrollElement === 'function') {
|
|
21665
21660
|
ionContent.getScrollElement().then((scrollElement) => {
|
|
21666
|
-
console.log('[SCROLL
|
|
21667
|
-
|
|
21668
|
-
scrollHeight: scrollElement.scrollHeight,
|
|
21669
|
-
clientHeight: scrollElement.clientHeight
|
|
21670
|
-
});
|
|
21671
|
-
// Store reference for use in scrollToSection and tooltips
|
|
21661
|
+
console.log('[SCROLL v6] Ionic scroll element ready - attaching listeners');
|
|
21662
|
+
// Store reference for tooltips and programmatic scrolling
|
|
21672
21663
|
this.embeddedScrollContainer = scrollElement;
|
|
21673
21664
|
this.tooltipService.setScrollContainer(scrollElement);
|
|
21674
|
-
//
|
|
21675
|
-
const checkInitialScroll = () => {
|
|
21676
|
-
const currentScrollTop = scrollElement.scrollTop;
|
|
21677
|
-
const scrollHeight = scrollElement.scrollHeight;
|
|
21678
|
-
const clientHeight = scrollElement.clientHeight;
|
|
21679
|
-
console.log('[SCROLL DEBUG v5] Checking initial scroll position', {
|
|
21680
|
-
scrollTop: currentScrollTop,
|
|
21681
|
-
scrollHeight,
|
|
21682
|
-
clientHeight,
|
|
21683
|
-
shouldCollapse: currentScrollTop > 50
|
|
21684
|
-
});
|
|
21685
|
-
// Only make a decision if we have substantial content
|
|
21686
|
-
if (scrollHeight < 500) {
|
|
21687
|
-
console.log('[SCROLL DEBUG v5] Content too small, skipping check');
|
|
21688
|
-
return;
|
|
21689
|
-
}
|
|
21690
|
-
if (currentScrollTop > 50) {
|
|
21691
|
-
console.log('[SCROLL DEBUG v5] Collapsing header due to scroll position', { currentScrollTop });
|
|
21692
|
-
this.isScrolled.set(true);
|
|
21693
|
-
}
|
|
21694
|
-
else {
|
|
21695
|
-
console.log('[SCROLL DEBUG v5] Expanding header due to scroll position', { currentScrollTop });
|
|
21696
|
-
this.isScrolled.set(false);
|
|
21697
|
-
}
|
|
21698
|
-
};
|
|
21699
|
-
// Use ResizeObserver to detect when content has finished rendering
|
|
21700
|
-
// Only check scroll position once content has substantial height
|
|
21701
|
-
const MIN_CONTENT_HEIGHT = 500; // Content should be at least this tall before we check scroll
|
|
21702
|
-
let lastHeight = scrollElement.scrollHeight;
|
|
21703
|
-
let stableCount = 0;
|
|
21704
|
-
let scrollCheckTimeout = null;
|
|
21705
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
21706
|
-
const currentHeight = scrollElement.scrollHeight;
|
|
21707
|
-
console.log('[SCROLL DEBUG v5] Content height changed', {
|
|
21708
|
-
lastHeight,
|
|
21709
|
-
currentHeight,
|
|
21710
|
-
stableCount,
|
|
21711
|
-
minHeightReached: currentHeight >= MIN_CONTENT_HEIGHT
|
|
21712
|
-
});
|
|
21713
|
-
// Clear any pending scroll check
|
|
21714
|
-
if (scrollCheckTimeout) {
|
|
21715
|
-
clearTimeout(scrollCheckTimeout);
|
|
21716
|
-
}
|
|
21717
|
-
// Only start checking when we have substantial content
|
|
21718
|
-
if (currentHeight >= MIN_CONTENT_HEIGHT) {
|
|
21719
|
-
if (currentHeight === lastHeight) {
|
|
21720
|
-
stableCount++;
|
|
21721
|
-
// Height has been stable for 2 consecutive observations
|
|
21722
|
-
if (stableCount >= 2) {
|
|
21723
|
-
console.log('[SCROLL DEBUG v5] Content height stabilized, scheduling scroll check');
|
|
21724
|
-
// Wait longer for Ionic to restore scroll position
|
|
21725
|
-
scrollCheckTimeout = setTimeout(() => {
|
|
21726
|
-
console.log('[SCROLL DEBUG v5] Performing delayed scroll check after stabilization');
|
|
21727
|
-
checkInitialScroll();
|
|
21728
|
-
}, 150);
|
|
21729
|
-
resizeObserver.disconnect();
|
|
21730
|
-
}
|
|
21731
|
-
}
|
|
21732
|
-
else {
|
|
21733
|
-
stableCount = 0;
|
|
21734
|
-
lastHeight = currentHeight;
|
|
21735
|
-
// Schedule a check after height change
|
|
21736
|
-
scrollCheckTimeout = setTimeout(() => {
|
|
21737
|
-
console.log('[SCROLL DEBUG v5] Checking scroll after height change');
|
|
21738
|
-
checkInitialScroll();
|
|
21739
|
-
}, 100);
|
|
21740
|
-
}
|
|
21741
|
-
}
|
|
21742
|
-
else {
|
|
21743
|
-
// Reset tracking if height drops below threshold (component being destroyed)
|
|
21744
|
-
stableCount = 0;
|
|
21745
|
-
lastHeight = currentHeight;
|
|
21746
|
-
}
|
|
21747
|
-
});
|
|
21748
|
-
// Observe the scroll element for size changes
|
|
21749
|
-
resizeObserver.observe(scrollElement);
|
|
21750
|
-
// Check immediately if we already have content, but allow time for scroll restoration
|
|
21751
|
-
if (scrollElement.scrollHeight >= MIN_CONTENT_HEIGHT) {
|
|
21752
|
-
scrollCheckTimeout = setTimeout(() => {
|
|
21753
|
-
console.log('[SCROLL DEBUG v5] Initial scroll check after delay');
|
|
21754
|
-
checkInitialScroll();
|
|
21755
|
-
}, 200);
|
|
21756
|
-
}
|
|
21757
|
-
// Attach scroll listeners
|
|
21665
|
+
// v6 - Only attach scroll event listeners, no initial state setting
|
|
21758
21666
|
scrollElement.addEventListener('scroll', () => this.onContainerScroll(scrollElement), { passive: true });
|
|
21759
21667
|
ionContent.addEventListener('ionScroll', () => this.onContainerScroll(scrollElement), { passive: true });
|
|
21760
|
-
|
|
21761
|
-
let lastScrollTop = 0;
|
|
21762
|
-
const pollScroll = () => {
|
|
21763
|
-
const currentScrollTop = scrollElement.scrollTop;
|
|
21764
|
-
if (currentScrollTop !== lastScrollTop) {
|
|
21765
|
-
lastScrollTop = currentScrollTop;
|
|
21766
|
-
this.onContainerScroll(scrollElement);
|
|
21767
|
-
}
|
|
21768
|
-
requestAnimationFrame(pollScroll);
|
|
21769
|
-
};
|
|
21770
|
-
requestAnimationFrame(pollScroll);
|
|
21668
|
+
console.log('[SCROLL v6] Event listeners attached - header responsive to scroll');
|
|
21771
21669
|
}).catch((error) => {
|
|
21772
|
-
console.error('Error getting Ionic scroll element:', error);
|
|
21670
|
+
console.error('[SCROLL v6] Error getting Ionic scroll element:', error);
|
|
21773
21671
|
});
|
|
21774
21672
|
return true;
|
|
21775
21673
|
}
|
|
21776
21674
|
else {
|
|
21777
21675
|
// Fallback for older Ionic versions
|
|
21778
|
-
console.log('[SCROLL
|
|
21779
|
-
scrollTop: element.scrollTop
|
|
21780
|
-
});
|
|
21676
|
+
console.log('[SCROLL v6] Using fallback for older Ionic');
|
|
21781
21677
|
this.embeddedScrollContainer = element;
|
|
21782
21678
|
this.tooltipService.setScrollContainer(element);
|
|
21783
|
-
// Helper function to check and update scroll state
|
|
21784
|
-
const checkInitialScroll = () => {
|
|
21785
|
-
const currentScrollTop = element.scrollTop;
|
|
21786
|
-
console.log('[SCROLL DEBUG v2] Checking initial scroll position (fallback)', {
|
|
21787
|
-
scrollTop: currentScrollTop,
|
|
21788
|
-
shouldCollapse: currentScrollTop > 50
|
|
21789
|
-
});
|
|
21790
|
-
if (currentScrollTop > 50) {
|
|
21791
|
-
console.log('[SCROLL DEBUG v2] Collapsing header due to scroll position', { currentScrollTop });
|
|
21792
|
-
this.isScrolled.set(true);
|
|
21793
|
-
}
|
|
21794
|
-
else {
|
|
21795
|
-
console.log('[SCROLL DEBUG v2] Expanding header due to scroll position', { currentScrollTop });
|
|
21796
|
-
this.isScrolled.set(false);
|
|
21797
|
-
}
|
|
21798
|
-
};
|
|
21799
|
-
// Use ResizeObserver to detect when content has finished rendering
|
|
21800
|
-
const MIN_CONTENT_HEIGHT = 500;
|
|
21801
|
-
let lastHeight = element.scrollHeight;
|
|
21802
|
-
let stableCount = 0;
|
|
21803
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
21804
|
-
const currentHeight = element.scrollHeight;
|
|
21805
|
-
console.log('[SCROLL DEBUG v2] Content height changed (fallback)', {
|
|
21806
|
-
lastHeight,
|
|
21807
|
-
currentHeight,
|
|
21808
|
-
stableCount,
|
|
21809
|
-
minHeightReached: currentHeight >= MIN_CONTENT_HEIGHT
|
|
21810
|
-
});
|
|
21811
|
-
if (currentHeight >= MIN_CONTENT_HEIGHT) {
|
|
21812
|
-
if (currentHeight === lastHeight) {
|
|
21813
|
-
stableCount++;
|
|
21814
|
-
if (stableCount >= 2) {
|
|
21815
|
-
console.log('[SCROLL DEBUG v2] Content height stabilized (fallback), checking scroll position');
|
|
21816
|
-
checkInitialScroll();
|
|
21817
|
-
resizeObserver.disconnect();
|
|
21818
|
-
}
|
|
21819
|
-
}
|
|
21820
|
-
else {
|
|
21821
|
-
stableCount = 0;
|
|
21822
|
-
lastHeight = currentHeight;
|
|
21823
|
-
checkInitialScroll();
|
|
21824
|
-
}
|
|
21825
|
-
}
|
|
21826
|
-
else {
|
|
21827
|
-
stableCount = 0;
|
|
21828
|
-
lastHeight = currentHeight;
|
|
21829
|
-
}
|
|
21830
|
-
});
|
|
21831
|
-
resizeObserver.observe(element);
|
|
21832
|
-
if (element.scrollHeight >= MIN_CONTENT_HEIGHT) {
|
|
21833
|
-
checkInitialScroll();
|
|
21834
|
-
}
|
|
21835
21679
|
element.addEventListener('scroll', () => this.onContainerScroll(element), { passive: true });
|
|
21836
21680
|
return true;
|
|
21837
21681
|
}
|
|
21838
21682
|
}
|
|
21839
21683
|
else {
|
|
21840
21684
|
// Regular HTML element
|
|
21841
|
-
console.log('[SCROLL
|
|
21842
|
-
scrollTop: element.scrollTop
|
|
21843
|
-
});
|
|
21685
|
+
console.log('[SCROLL v6] Regular HTML element');
|
|
21844
21686
|
this.embeddedScrollContainer = element;
|
|
21845
21687
|
this.tooltipService.setScrollContainer(element);
|
|
21846
|
-
// Helper function to check and update scroll state
|
|
21847
|
-
const checkInitialScroll = () => {
|
|
21848
|
-
const currentScrollTop = element.scrollTop;
|
|
21849
|
-
console.log('[SCROLL DEBUG v2] Checking initial scroll position (regular)', {
|
|
21850
|
-
scrollTop: currentScrollTop,
|
|
21851
|
-
shouldCollapse: currentScrollTop > 50
|
|
21852
|
-
});
|
|
21853
|
-
if (currentScrollTop > 50) {
|
|
21854
|
-
console.log('[SCROLL DEBUG v2] Collapsing header due to scroll position', { currentScrollTop });
|
|
21855
|
-
this.isScrolled.set(true);
|
|
21856
|
-
}
|
|
21857
|
-
else {
|
|
21858
|
-
console.log('[SCROLL DEBUG v2] Expanding header due to scroll position', { currentScrollTop });
|
|
21859
|
-
this.isScrolled.set(false);
|
|
21860
|
-
}
|
|
21861
|
-
};
|
|
21862
|
-
// Use ResizeObserver to detect when content has finished rendering
|
|
21863
|
-
const MIN_CONTENT_HEIGHT = 500;
|
|
21864
|
-
let lastHeight = element.scrollHeight;
|
|
21865
|
-
let stableCount = 0;
|
|
21866
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
21867
|
-
const currentHeight = element.scrollHeight;
|
|
21868
|
-
console.log('[SCROLL DEBUG v2] Content height changed (regular)', {
|
|
21869
|
-
lastHeight,
|
|
21870
|
-
currentHeight,
|
|
21871
|
-
stableCount,
|
|
21872
|
-
minHeightReached: currentHeight >= MIN_CONTENT_HEIGHT
|
|
21873
|
-
});
|
|
21874
|
-
if (currentHeight >= MIN_CONTENT_HEIGHT) {
|
|
21875
|
-
if (currentHeight === lastHeight) {
|
|
21876
|
-
stableCount++;
|
|
21877
|
-
if (stableCount >= 2) {
|
|
21878
|
-
console.log('[SCROLL DEBUG v2] Content height stabilized (regular), checking scroll position');
|
|
21879
|
-
checkInitialScroll();
|
|
21880
|
-
resizeObserver.disconnect();
|
|
21881
|
-
}
|
|
21882
|
-
}
|
|
21883
|
-
else {
|
|
21884
|
-
stableCount = 0;
|
|
21885
|
-
lastHeight = currentHeight;
|
|
21886
|
-
checkInitialScroll();
|
|
21887
|
-
}
|
|
21888
|
-
}
|
|
21889
|
-
else {
|
|
21890
|
-
stableCount = 0;
|
|
21891
|
-
lastHeight = currentHeight;
|
|
21892
|
-
}
|
|
21893
|
-
});
|
|
21894
|
-
resizeObserver.observe(element);
|
|
21895
|
-
if (element.scrollHeight >= MIN_CONTENT_HEIGHT) {
|
|
21896
|
-
checkInitialScroll();
|
|
21897
|
-
}
|
|
21898
21688
|
element.addEventListener('scroll', () => this.onContainerScroll(element), { passive: true });
|
|
21899
21689
|
return true;
|
|
21900
21690
|
}
|
|
21901
21691
|
};
|
|
21902
21692
|
// Try to set up immediately
|
|
21903
21693
|
if (!setupScrollContainer()) {
|
|
21904
|
-
//
|
|
21694
|
+
// Retry if element not found yet
|
|
21905
21695
|
let retries = 0;
|
|
21906
21696
|
const maxRetries = 10;
|
|
21907
21697
|
const retryInterval = setInterval(() => {
|
|
@@ -21909,7 +21699,7 @@ class SymphiqFunnelAnalysisDashboardComponent {
|
|
|
21909
21699
|
if (setupScrollContainer() || retries >= maxRetries) {
|
|
21910
21700
|
clearInterval(retryInterval);
|
|
21911
21701
|
if (retries >= maxRetries) {
|
|
21912
|
-
console.warn(`
|
|
21702
|
+
console.warn(`[SCROLL v6] Container "${this.scrollContainerId()}" not found after ${maxRetries} retries`);
|
|
21913
21703
|
}
|
|
21914
21704
|
}
|
|
21915
21705
|
}, 100);
|
|
@@ -22134,11 +21924,9 @@ class SymphiqFunnelAnalysisDashboardComponent {
|
|
|
22134
21924
|
return;
|
|
22135
21925
|
}
|
|
22136
21926
|
const scrollPosition = container.scrollTop;
|
|
22137
|
-
console.log('[SCROLL
|
|
21927
|
+
console.log('[SCROLL v6] onContainerScroll', {
|
|
22138
21928
|
scrollPosition,
|
|
22139
|
-
|
|
22140
|
-
isProgrammaticScroll: this.isProgrammaticScroll,
|
|
22141
|
-
lastScrollPosition: this.lastScrollPosition
|
|
21929
|
+
currentState: this.isScrolled()
|
|
22142
21930
|
});
|
|
22143
21931
|
// Update scroll progress for smooth bar animation
|
|
22144
21932
|
const containerHeight = container.clientHeight;
|
|
@@ -22146,39 +21934,23 @@ class SymphiqFunnelAnalysisDashboardComponent {
|
|
|
22146
21934
|
const maxScroll = scrollHeight - containerHeight;
|
|
22147
21935
|
const progress = maxScroll > 0 ? (scrollPosition / maxScroll) * 100 : 0;
|
|
22148
21936
|
this.scrollProgress.set(Math.min(100, Math.max(0, progress)));
|
|
22149
|
-
// Skip header state updates during programmatic scrolling
|
|
21937
|
+
// Skip header state updates during programmatic scrolling
|
|
22150
21938
|
if (this.isProgrammaticScroll) {
|
|
22151
|
-
console.log('[SCROLL
|
|
21939
|
+
console.log('[SCROLL v6] Skipping - programmatic scroll');
|
|
22152
21940
|
return;
|
|
22153
21941
|
}
|
|
22154
|
-
|
|
22155
|
-
const timeSinceLastChange = now - this.lastStateChangeTime;
|
|
22156
|
-
if (timeSinceLastChange < this.STATE_CHANGE_COOLDOWN) {
|
|
22157
|
-
console.log('[SCROLL DEBUG] Skipping - within cooldown', { timeSinceLastChange });
|
|
22158
|
-
return;
|
|
22159
|
-
}
|
|
22160
|
-
if (this.scrollTimeout) {
|
|
22161
|
-
clearTimeout(this.scrollTimeout);
|
|
22162
|
-
}
|
|
22163
|
-
// Use hysteresis to prevent bounce
|
|
21942
|
+
// v6 - Simple threshold-based state changes with hysteresis
|
|
22164
21943
|
const COLLAPSE_THRESHOLD = 50;
|
|
22165
21944
|
const EXPAND_THRESHOLD = 30;
|
|
22166
21945
|
const currentState = this.isScrolled();
|
|
22167
|
-
let newState = currentState;
|
|
22168
21946
|
if (!currentState && scrollPosition > COLLAPSE_THRESHOLD) {
|
|
22169
|
-
|
|
22170
|
-
|
|
21947
|
+
console.log('[SCROLL v6] Collapsing header', { scrollPosition });
|
|
21948
|
+
this.isScrolled.set(true);
|
|
22171
21949
|
}
|
|
22172
21950
|
else if (currentState && scrollPosition < EXPAND_THRESHOLD) {
|
|
22173
|
-
|
|
22174
|
-
|
|
22175
|
-
}
|
|
22176
|
-
if (newState !== currentState) {
|
|
22177
|
-
console.log('[SCROLL DEBUG] Changing header state', { from: currentState, to: newState });
|
|
22178
|
-
this.isScrolled.set(newState);
|
|
22179
|
-
this.lastStateChangeTime = Date.now();
|
|
21951
|
+
console.log('[SCROLL v6] Expanding header', { scrollPosition });
|
|
21952
|
+
this.isScrolled.set(false);
|
|
22180
21953
|
}
|
|
22181
|
-
this.lastScrollPosition = scrollPosition;
|
|
22182
21954
|
}
|
|
22183
21955
|
onScroll() {
|
|
22184
21956
|
if (this.embedded()) {
|