From 579e707ea0b24991ddb202591c86f204fdf3195f Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Thu, 25 Sep 2025 19:37:41 +0200 Subject: [PATCH 1/4] fix: scroll to wrong section --- Website/components/datamodelview/List.tsx | 73 ++--------------------- 1 file changed, 6 insertions(+), 67 deletions(-) diff --git a/Website/components/datamodelview/List.tsx b/Website/components/datamodelview/List.tsx index 7770d34..6bf328b 100644 --- a/Website/components/datamodelview/List.tsx +++ b/Website/components/datamodelview/List.tsx @@ -8,7 +8,7 @@ import { AttributeType, EntityType, GroupType } from "@/lib/Types"; import { updateURL } from "@/lib/url-utils"; import { copyToClipboard, generateGroupLink } from "@/lib/clipboard-utils"; import { useSnackbar } from "@/contexts/SnackbarContext"; -import { debounce, Tooltip } from '@mui/material'; +import { Backdrop, Box, CircularProgress, debounce, Paper, Skeleton, Tooltip } from '@mui/material'; interface IListProps { setCurrentIndex: (index: number) => void; @@ -24,12 +24,10 @@ export function highlightMatch(text: string, search: string) { export const List = ({ setCurrentIndex }: IListProps) => { const dispatch = useDatamodelViewDispatch(); - const { currentSection, loading } = useDatamodelView(); + const { currentSection, loading, loadingSection } = useDatamodelView(); const { groups, filtered, search } = useDatamodelData(); const { showSnackbar } = useSnackbar(); const parentRef = useRef(null); - const scrollTimeoutRef = useRef(); - const scrollingRef = React.useRef() // used to relocate section after search/filter const [sectionVirtualItem, setSectionVirtualItem] = useState(null); @@ -79,34 +77,6 @@ export const List = ({ setCurrentIndex }: IListProps) => { return items; }, [filtered, search, groups]); - function easeInOutQuint(t: number) { - return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t - } - - const scrollToFn: VirtualizerOptions['scrollToFn'] = - React.useCallback((offset, canSmooth, instance) => { - const duration = 2000 - const start = parentRef.current?.scrollTop || 0 - const startTime = (scrollingRef.current = Date.now()) - - const run = () => { - if (scrollingRef.current !== startTime) return - const now = Date.now() - const elapsed = now - startTime - const progress = easeInOutQuint(Math.min(elapsed / duration, 1)) - const interpolated = start + (offset - start) * progress - - if (elapsed < duration) { - elementScroll(interpolated, canSmooth, instance) - requestAnimationFrame(run) - } else { - elementScroll(interpolated, canSmooth, instance) - } - } - - requestAnimationFrame(run) - }, []) - const debouncedOnChange = debounce((instance, sync) => { if (!sync) { dispatch({ type: 'SET_LOADING_SECTION', payload: null }); @@ -176,15 +146,10 @@ export const List = ({ setCurrentIndex }: IListProps) => { if (!item) return 200; return item.type === 'group' ? 100 : 500; }, - scrollToFn, onChange: debouncedOnChange, }); const scrollToSection = useCallback((sectionId: string) => { - if (scrollTimeoutRef.current) { - clearTimeout(scrollTimeoutRef.current); - } - const sectionIndex = flatItems.findIndex(item => item.type === 'entity' && item.entity.SchemaName === sectionId ); @@ -195,16 +160,13 @@ export const List = ({ setCurrentIndex }: IListProps) => { } rowVirtualizer.scrollToIndex(sectionIndex, { - align: 'start' + align: 'start', + behavior: 'smooth' }); }, [flatItems]); const scrollToGroup = useCallback((groupName: string) => { - if (scrollTimeoutRef.current) { - clearTimeout(scrollTimeoutRef.current); - } - const groupIndex = flatItems.findIndex(item => item.type === 'group' && item.group.Name === groupName ); @@ -215,7 +177,8 @@ export const List = ({ setCurrentIndex }: IListProps) => { } rowVirtualizer.scrollToIndex(groupIndex, { - align: 'start' + align: 'start', + behavior: 'smooth' }); }, [flatItems]); @@ -229,12 +192,6 @@ export const List = ({ setCurrentIndex }: IListProps) => { dispatch({ type: 'SET_SCROLL_TO_SECTION', payload: scrollToSection }); dispatch({ type: 'SET_SCROLL_TO_GROUP', payload: scrollToGroup }); dispatch({ type: 'SET_RESTORE_SECTION', payload: restoreSection }); - - return () => { - if (scrollTimeoutRef.current) { - clearTimeout(scrollTimeoutRef.current); - } - }; }, [dispatch, scrollToSection, scrollToGroup]); // Callback to handle section content changes (for tab switches, expansions, etc.) @@ -250,24 +207,6 @@ export const List = ({ setCurrentIndex }: IListProps) => { return (
- {/* Show skeleton loading state only when initially loading */} - {flatItems.length === 0 && loading && (!search || search.length < 3) && ( -
- {[...Array(5)].map((_, i) => ( -
-
-
-
-
-
-
-
-
-
- ))} -
- )} - {/* Show no results message when searching but no items found */} {flatItems.length === 0 && search && search.length >= 3 && (
From 7fe1c44342565d9c0aa6f9bf169b1907054e5d6f Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Thu, 25 Sep 2025 19:40:34 +0200 Subject: [PATCH 2/4] fix: tablesearch not working after previous version --- Website/components/datamodelview/SidebarDatamodelView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/components/datamodelview/SidebarDatamodelView.tsx b/Website/components/datamodelview/SidebarDatamodelView.tsx index ebd7503..bfe8e6e 100644 --- a/Website/components/datamodelview/SidebarDatamodelView.tsx +++ b/Website/components/datamodelview/SidebarDatamodelView.tsx @@ -42,7 +42,7 @@ export const SidebarDatamodelView = ({ }: ISidebarDatamodelViewProps) => { Entities: group.Entities.filter(entity => (entity.SchemaName.toLowerCase().includes(searchTerm.toLowerCase()) || entity.DisplayName.toLowerCase().includes(searchTerm.toLowerCase())) && - filtered.some(f => f.type === 'entity' && f.entity.SchemaName === entity.SchemaName) + (!search || filtered.some(f => f.type === 'entity' && f.entity.SchemaName === entity.SchemaName)) ) })).filter(group => group.Entities.length > 0); }, [groups, searchTerm, filtered]); From 10848df0a4721e45132fc7e52c6c049e92d6b7ec Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Thu, 25 Sep 2025 19:56:40 +0200 Subject: [PATCH 3/4] fix: restore correct location on clear --- Website/components/datamodelview/DatamodelView.tsx | 5 ++++- Website/components/datamodelview/List.tsx | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Website/components/datamodelview/DatamodelView.tsx b/Website/components/datamodelview/DatamodelView.tsx index b28b7e5..00caa2a 100644 --- a/Website/components/datamodelview/DatamodelView.tsx +++ b/Website/components/datamodelview/DatamodelView.tsx @@ -47,8 +47,11 @@ function DatamodelViewContent() { } else { // Clear search - reset to show all groups datamodelDataDispatch({ type: "SET_FILTERED", payload: [] }); + // Relocate section - restoreSection(); + if (searchValue && searchValue.length === 0) { + restoreSection(); + } } } updateURL({ query: { globalsearch: searchValue.length >= 3 ? searchValue : "" } }) diff --git a/Website/components/datamodelview/List.tsx b/Website/components/datamodelview/List.tsx index 6bf328b..303ff3a 100644 --- a/Website/components/datamodelview/List.tsx +++ b/Website/components/datamodelview/List.tsx @@ -1,14 +1,14 @@ import { useEffect, useMemo, useRef, useCallback, useState } from "react"; import { useDatamodelView, useDatamodelViewDispatch } from "@/contexts/DatamodelViewContext"; import React from "react"; -import { elementScroll, useVirtualizer, VirtualizerOptions } from '@tanstack/react-virtual'; +import { useVirtualizer } from '@tanstack/react-virtual'; import { Section } from "./Section"; import { useDatamodelData } from "@/contexts/DatamodelDataContext"; import { AttributeType, EntityType, GroupType } from "@/lib/Types"; import { updateURL } from "@/lib/url-utils"; import { copyToClipboard, generateGroupLink } from "@/lib/clipboard-utils"; import { useSnackbar } from "@/contexts/SnackbarContext"; -import { Backdrop, Box, CircularProgress, debounce, Paper, Skeleton, Tooltip } from '@mui/material'; +import { debounce, Tooltip } from '@mui/material'; interface IListProps { setCurrentIndex: (index: number) => void; @@ -24,7 +24,7 @@ export function highlightMatch(text: string, search: string) { export const List = ({ setCurrentIndex }: IListProps) => { const dispatch = useDatamodelViewDispatch(); - const { currentSection, loading, loadingSection } = useDatamodelView(); + const { currentSection } = useDatamodelView(); const { groups, filtered, search } = useDatamodelData(); const { showSnackbar } = useSnackbar(); const parentRef = useRef(null); @@ -128,8 +128,11 @@ export const List = ({ setCurrentIndex }: IListProps) => { } } - if (mostVisibleEntity && currentSection !== mostVisibleEntity.entity.SchemaName) { + if (mostVisibleEntity && !search) { setSectionVirtualItem(mostVisibleEntity.entity.SchemaName); + } + + if (mostVisibleEntity && currentSection !== mostVisibleEntity.entity.SchemaName) { updateURL({ query: { group: mostVisibleEntity.group.Name, section: mostVisibleEntity.entity.SchemaName } }); dispatch({ type: "SET_CURRENT_GROUP", payload: mostVisibleEntity.group.Name }); dispatch({ type: "SET_CURRENT_SECTION", payload: mostVisibleEntity.entity.SchemaName }); From cdde88a76df9ccdb2885e8484c75fd883210cfea Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Thu, 25 Sep 2025 19:58:36 +0200 Subject: [PATCH 4/4] fix: clear menuitem in search info menu --- Website/components/datamodelview/TimeSlicedSearch.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/components/datamodelview/TimeSlicedSearch.tsx b/Website/components/datamodelview/TimeSlicedSearch.tsx index aaa5247..9ff5874 100644 --- a/Website/components/datamodelview/TimeSlicedSearch.tsx +++ b/Website/components/datamodelview/TimeSlicedSearch.tsx @@ -170,7 +170,7 @@ export const TimeSlicedSearch = ({ if (typingTimeoutRef.current) { clearTimeout(typingTimeoutRef.current); } - }, [onSearch, onLoadingChange]); + }, [onSearch, onLoadingChange, localValue]); // Cleanup useEffect(() => {