From d94ece5fe39742cfd22e8ac1a3f852dc825dec6a Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 13:19:52 +0200 Subject: [PATCH 01/14] fix: removed inconsistent smooth scrolling and added spinner on section loading --- Website/components/datamodelview/List.tsx | 168 +++++++++++----------- 1 file changed, 86 insertions(+), 82 deletions(-) diff --git a/Website/components/datamodelview/List.tsx b/Website/components/datamodelview/List.tsx index 303ff3a..90822e0 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 { Box, CircularProgress, 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 } = useDatamodelView(); + const { currentSection, loadingSection } = useDatamodelView(); const { groups, filtered, search } = useDatamodelData(); const { showSnackbar } = useSnackbar(); const parentRef = useRef(null); @@ -163,8 +163,7 @@ export const List = ({ setCurrentIndex }: IListProps) => { } rowVirtualizer.scrollToIndex(sectionIndex, { - align: 'start', - behavior: 'smooth' + align: 'start' }); }, [flatItems]); @@ -180,8 +179,7 @@ export const List = ({ setCurrentIndex }: IListProps) => { } rowVirtualizer.scrollToIndex(groupIndex, { - align: 'start', - behavior: 'smooth' + align: 'start' }); }, [flatItems]); @@ -208,85 +206,91 @@ export const List = ({ setCurrentIndex }: IListProps) => { }, [rowVirtualizer]); return ( -
+ <> + + + +
- {/* Show no results message when searching but no items found */} - {flatItems.length === 0 && search && search.length >= 3 && ( -
-
No tables found
-
- No attributes match your search for "{search}" + {/* Show no results message when searching but no items found */} + {flatItems.length === 0 && search && search.length >= 3 && ( +
+
No tables found
+
+ No attributes match your search for "{search}" +
-
- )} - - {/* Virtualized list */} -
- {rowVirtualizer.getVirtualItems().map((virtualItem) => { - const item = flatItems[virtualItem.index]; + )} + + {/* Virtualized list */} +
+ {rowVirtualizer.getVirtualItems().map((virtualItem) => { + const item = flatItems[virtualItem.index]; - return ( -
{ - if (el) { - // trigger remeasurement when content changes and load - requestAnimationFrame(() => { - handleSectionResize(virtualItem.index); - }); - } - }} - > - {item.type === 'group' ? ( -
-
- -
handleCopyGroupLink(item.group.Name)} - > - {item.group.Name} -
-
-
-
- ) : ( -
-
{ - isTabSwitching.current = isChanging; - if (isChanging) { - // Reset after a short delay to allow for the content change - setTimeout(() => { - isTabSwitching.current = false; - }, 100); - } - }} - search={search} - /> -
- )} -
- ); - })} + return ( +
{ + if (el) { + // trigger remeasurement when content changes and load + requestAnimationFrame(() => { + handleSectionResize(virtualItem.index); + }); + } + }} + > + {item.type === 'group' ? ( +
+
+ +
handleCopyGroupLink(item.group.Name)} + > + {item.group.Name} +
+
+
+
+ ) : ( +
+
{ + isTabSwitching.current = isChanging; + if (isChanging) { + // Reset after a short delay to allow for the content change + setTimeout(() => { + isTabSwitching.current = false; + }, 100); + } + }} + search={search} + /> +
+ )} +
+ ); + })} +
-
+ ); }; From 4666d956427265b64dbd6b97b02788c975cafa76 Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 13:25:33 +0200 Subject: [PATCH 02/14] chore: removed new badge and spin animation for settings --- Website/components/shared/Header.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Website/components/shared/Header.tsx b/Website/components/shared/Header.tsx index c8449d6..9b11975 100644 --- a/Website/components/shared/Header.tsx +++ b/Website/components/shared/Header.tsx @@ -87,12 +87,10 @@ const Header = ({ }: HeaderProps) => { className='flex flex-col items-center p-1.5 rounded-lg text-gray-400 min-w-0' onClick={handleSettingsClick} > - - - - - - + + + + {isAuthenticated && ( <> From 1ea712c08831b629db6f472fc8ed880fab127108 Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 13:27:17 +0200 Subject: [PATCH 03/14] chore: removed new flags on navigation for home and processes --- Website/components/shared/Sidebar.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/Website/components/shared/Sidebar.tsx b/Website/components/shared/Sidebar.tsx index a09c7ad..e29e631 100644 --- a/Website/components/shared/Sidebar.tsx +++ b/Website/components/shared/Sidebar.tsx @@ -34,7 +34,6 @@ const Sidebar = ({ }: SidebarProps) => { href: '/', icon: , active: pathname === '/', - new: true, }, { label: 'Insights', @@ -60,7 +59,6 @@ const Sidebar = ({ }: SidebarProps) => { href: '/processes', icon: , active: pathname === '/processes', - new: true, } ]; From 447defb3197c9c24b499e490f488191846eb360e Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 13:35:58 +0200 Subject: [PATCH 04/14] fix: removed large logo and used typo instead --- Website/components/aboutview/AboutView.tsx | 19 +++++++++++++------ Website/public/DMVLOGOHORZ.svg | 1 - 2 files changed, 13 insertions(+), 7 deletions(-) delete mode 100644 Website/public/DMVLOGOHORZ.svg diff --git a/Website/components/aboutview/AboutView.tsx b/Website/components/aboutview/AboutView.tsx index 6f6e0e4..4f579df 100644 --- a/Website/components/aboutview/AboutView.tsx +++ b/Website/components/aboutview/AboutView.tsx @@ -25,12 +25,19 @@ export const AboutView = ({}: IAboutViewProps) => { {/* Logo */} - + + + + DATA MODEL + VIEWER + @ DELEGATE | CONTEXT& + + {/* What is DMV */} diff --git a/Website/public/DMVLOGOHORZ.svg b/Website/public/DMVLOGOHORZ.svg deleted file mode 100644 index 109a38e..0000000 --- a/Website/public/DMVLOGOHORZ.svg +++ /dev/null @@ -1 +0,0 @@ -@Delegate \ No newline at end of file From 98707d9688f691160b8d64bd4de6617d814d4efe Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 13:42:51 +0200 Subject: [PATCH 05/14] chore: changed alignment of icon and removed large gap between table name and schemaname --- Website/components/datamodelview/entity/EntityHeader.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Website/components/datamodelview/entity/EntityHeader.tsx b/Website/components/datamodelview/entity/EntityHeader.tsx index 289d9e3..907176a 100644 --- a/Website/components/datamodelview/entity/EntityHeader.tsx +++ b/Website/components/datamodelview/entity/EntityHeader.tsx @@ -30,9 +30,10 @@ export function EntityHeader({ entity }: { entity: EntityType }) { pr: { xl: 3, xs: 0 } }} > - + - + Date: Sun, 28 Sep 2025 13:45:54 +0200 Subject: [PATCH 06/14] fix: changed single-select to be radio buttons instead of checkboxes --- .../components/datamodelview/attributes/ChoiceAttribute.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Website/components/datamodelview/attributes/ChoiceAttribute.tsx b/Website/components/datamodelview/attributes/ChoiceAttribute.tsx index 74881a8..972a8d8 100644 --- a/Website/components/datamodelview/attributes/ChoiceAttribute.tsx +++ b/Website/components/datamodelview/attributes/ChoiceAttribute.tsx @@ -2,7 +2,7 @@ import { useIsMobile } from "@/hooks/use-mobile" import { ChoiceAttributeType } from "@/lib/Types" import { formatNumberSeperator } from "@/lib/utils" import { Box, Typography, Chip } from "@mui/material" -import { CheckBoxOutlineBlankRounded, CheckBoxRounded, CheckRounded } from "@mui/icons-material" +import { CheckBoxOutlineBlankRounded, CheckBoxRounded, CheckRounded, RadioButtonChecked, RadioButtonCheckedRounded, RadioButtonUncheckedRounded } from "@mui/icons-material" export default function ChoiceAttribute({ attribute, highlightMatch, highlightTerm }: { attribute: ChoiceAttributeType, highlightMatch: (text: string, term: string) => string | React.JSX.Element, highlightTerm: string }) { @@ -38,9 +38,9 @@ export default function ChoiceAttribute({ attribute, highlightMatch, highlightTe ) : ( // For single-select, show radio buttons option.Value === attribute.DefaultValue ? ( - + ) : ( - + ) )} {highlightMatch(option.Name, highlightTerm)} From 732235c9edb2e3372670e84bba25f0b2576e5f24 Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 14:51:37 +0200 Subject: [PATCH 07/14] feat: navigation to processes from metadata --- .../components/datamodelview/Attributes.tsx | 2 +- .../datamodelview/entity/AttributeDetails.tsx | 30 +++++++--------- .../processesview/ProcessesView.tsx | 35 +++++++++++++++---- 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/Website/components/datamodelview/Attributes.tsx b/Website/components/datamodelview/Attributes.tsx index cebe4f8..0136830 100644 --- a/Website/components/datamodelview/Attributes.tsx +++ b/Website/components/datamodelview/Attributes.tsx @@ -388,7 +388,7 @@ export const Attributes = ({ entity, onVisibleCountChange, search = "" }: IAttri {highlightMatch(attribute.SchemaName, highlightTerm)} {getAttributeComponent(entity, attribute, highlightMatch, highlightTerm)} - + {highlightMatch(attribute.Description ?? "", highlightTerm)} diff --git a/Website/components/datamodelview/entity/AttributeDetails.tsx b/Website/components/datamodelview/entity/AttributeDetails.tsx index c3b1969..1bbde84 100644 --- a/Website/components/datamodelview/entity/AttributeDetails.tsx +++ b/Website/components/datamodelview/entity/AttributeDetails.tsx @@ -1,10 +1,10 @@ 'use client' -import { AttributeType, CalculationMethods, ComponentType, RequiredLevel } from "@/lib/Types"; -import { AccountTreeRounded, AddCircleOutlineRounded, CalculateRounded, ElectricBoltRounded, ErrorRounded, FunctionsRounded, JavascriptRounded, LockRounded, VisibilityRounded } from "@mui/icons-material"; -import { Tooltip } from "@mui/material"; +import { AttributeType, CalculationMethods, RequiredLevel } from "@/lib/Types"; +import { AddCircleOutlineRounded, CalculateRounded, ElectricBoltRounded, ErrorRounded, FunctionsRounded, LockRounded, VisibilityRounded } from "@mui/icons-material"; +import { Link, Tooltip } from "@mui/material"; -export function AttributeDetails({ attribute }: { attribute: AttributeType }) { +export function AttributeDetails({ entityName, attribute }: { entityName: string, attribute: AttributeType }) { const details = []; switch (attribute.RequiredLevel) { @@ -34,21 +34,15 @@ export function AttributeDetails({ attribute }: { attribute: AttributeType }) { details.push({ icon: , tooltip: "Field Security" }); } - if (attribute.AttributeUsages.some(a => a.ComponentType == ComponentType.Plugin)) { - const tooltip = `Plugins ${attribute.AttributeUsages.filter(au => au.ComponentType == ComponentType.Plugin).map(au => au.Name).join(", ")}`; - details.push({ icon: , tooltip }); + if (attribute.AttributeUsages.length > 0) { + const tooltip = Processes ${attribute.AttributeUsages.map(au => au.Name).join(", ")}.
Click to see more details.
; + details.push({ icon: ( + + + + ), tooltip }); } - - if (attribute.AttributeUsages.some(a => a.ComponentType == ComponentType.PowerAutomateFlow)) { - const tooltip = `Power Automate Flows ${attribute.AttributeUsages.filter(au => au.ComponentType == ComponentType.PowerAutomateFlow).map(au => au.Name).join(", ")}`; - details.push({ icon: , tooltip }); - } - - if (attribute.AttributeUsages.some(a => a.ComponentType == ComponentType.WebResource)) { - const tooltip = `Web Resources ${attribute.AttributeUsages.filter(au => au.ComponentType == ComponentType.WebResource).map(au => au.Name).join(", ")}`; - details.push({ icon: , tooltip }); - } - + return (
{details.map((detail, index) => ( diff --git a/Website/components/processesview/ProcessesView.tsx b/Website/components/processesview/ProcessesView.tsx index d6e6aa7..6a85552 100644 --- a/Website/components/processesview/ProcessesView.tsx +++ b/Website/components/processesview/ProcessesView.tsx @@ -10,6 +10,7 @@ import LoadingOverlay from '@/components/shared/LoadingOverlay' import NotchedBox from '../shared/elements/NotchedBox' import { StatCard } from '../shared/elements/StatCard' import { ResponsivePie } from '@nivo/pie' +import { useSearchParams } from 'next/navigation' interface IProcessesViewProps { } @@ -26,11 +27,31 @@ export const ProcessesView = ({ }: IProcessesViewProps) => { const [searchTerm, setSearchTerm] = useState('') const [isSearching, setIsSearching] = useState(false) const [selectedAttribute, setSelectedAttribute] = useState(null) + const initialAttribute = useSearchParams().get('attr') || ""; + const initialEntity = useSearchParams().get('ent') || ""; useEffect(() => { setElement(null); close(); - }, [setElement, close]) + + if (initialAttribute && initialEntity && groups.length > 0) { + const d = groups.flatMap(group => + group.Entities.flatMap(entity => + entity.Attributes.map(attribute => ({ + attribute, + entity, + group: group.Name, + })) + ) + ); + const foundAttribute = d.find(result => + result.attribute.SchemaName === initialAttribute + && result.entity.SchemaName === initialEntity); + if (foundAttribute) { + setSelectedAttribute(foundAttribute); + } + } + }, [groups]) const typeDistribution = useMemo(() => { return groups.reduce((acc, group) => { @@ -111,13 +132,13 @@ export const ProcessesView = ({ }: IProcessesViewProps) => { // Simulate search delay for UX useEffect(() => { if (searchTerm.trim() && searchTerm.length >= 2) { - setIsSearching(true) - const timer = setTimeout(() => { - setIsSearching(false) - }, 300) - return () => clearTimeout(timer) + setIsSearching(true) + const timer = setTimeout(() => { + setIsSearching(false) + }, 300) + return () => clearTimeout(timer) } else { - setIsSearching(false) + setIsSearching(false) } }, [searchTerm]) From b6969c7dd3ebd414b463ed3bbd53a68eefbec5bf Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 15:12:41 +0200 Subject: [PATCH 08/14] fix: fix default height on homepage and removed ado page error when no page is found --- Website/app/api/markdown/route.ts | 6 +-- Website/components/homeview/HomeView.tsx | 60 +++++++++++++++--------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/Website/app/api/markdown/route.ts b/Website/app/api/markdown/route.ts index a0037a6..49aa73b 100644 --- a/Website/app/api/markdown/route.ts +++ b/Website/app/api/markdown/route.ts @@ -4,13 +4,11 @@ import { join } from "path"; export async function GET() { const generatedPath = join(process.cwd(), 'generated', 'Introduction.md'); - const stubsPath = join(process.cwd(), 'stubs', 'Introduction.md'); - let fileContent; + let fileContent = undefined; try { fileContent = readFileSync(generatedPath, 'utf-8'); } catch (error) { - fileContent = readFileSync(stubsPath, 'utf-8'); - console.error('Error reading generated wiki file, falling back to stubs:', error); + return NextResponse.json({ error: 'File not found' }, { status: 404 }); } return NextResponse.json({ fileContent }) } diff --git a/Website/components/homeview/HomeView.tsx b/Website/components/homeview/HomeView.tsx index 459870d..807b6b2 100644 --- a/Website/components/homeview/HomeView.tsx +++ b/Website/components/homeview/HomeView.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from 'react'; import { useSidebar } from '@/contexts/SidebarContext' import Markdown from 'react-markdown' -import { Box, Button, Grid, IconButton, Paper, Typography } from '@mui/material'; +import { Box, Button, CircularProgress, Grid, IconButton, Paper, Typography } from '@mui/material'; import NotchedBox from '@/components/shared/elements/NotchedBox'; import Carousel, { CarouselItem } from '@/components/shared/elements/Carousel'; import { ChevronLeftRounded, ChevronRightRounded } from '@mui/icons-material'; @@ -17,7 +17,7 @@ export const HomeView = ({ }: IHomeViewProps) => { const router = useRouter(); - const [wikipage, setWikipage] = useState(''); + const [wikipage, setWikipage] = useState(''); const [currentCarouselIndex, setCurrentCarouselIndex] = useState(0); const [slideDirection, setSlideDirection] = useState<'left' | 'right' | null>(null); @@ -65,12 +65,24 @@ export const HomeView = ({ }: IHomeViewProps) => { setElement(null); close(); fetch('/api/markdown') - .then(res => res.json()) - .then(data => setWikipage(data.fileContent.replace(/\\n/g, '\n'))); + .then(res => { + return res.json(); + }) + .then(data => { + if (data.fileContent) { + setWikipage(data.fileContent.replace(/\\n/g, '\n')); + } else { + setWikipage(undefined); + } + }) + .catch(error => { + console.error('Error fetching wiki page:', error); + setWikipage(undefined); + }); }, []); return ( - + { - - {wikipage ? ( -

, - h2: ({ ...props }) =>

, - h3: ({ ...props }) =>

, - h4: ({ ...props }) =>

, - p: ({ ...props }) =>

, - a: ({ ...props }) => , - li: ({ ...props }) =>

  • , - span: ({ ...props }) => , - img: ({ ...props }) => , - }}>{wikipage} - ) : ( -
    Loading wiki...
    - )} - + { + wikipage !== undefined && ( + + {wikipage.length > 0 ? ( +

    , + h2: ({ ...props }) =>

    , + h3: ({ ...props }) =>

    , + h4: ({ ...props }) =>

    , + p: ({ ...props }) =>

    , + a: ({ ...props }) => , + li: ({ ...props }) =>

  • , + span: ({ ...props }) => , + img: ({ ...props }) => , + }}>{wikipage} + ) : ( + Loading wiki page... + )} + + ) + } From f663e65c804788f3f021e2b97534aa4f5d964db7 Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 15:14:54 +0200 Subject: [PATCH 09/14] chore: removed next error by checking wiki location first --- Website/app/api/markdown/route.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Website/app/api/markdown/route.ts b/Website/app/api/markdown/route.ts index 49aa73b..59a3319 100644 --- a/Website/app/api/markdown/route.ts +++ b/Website/app/api/markdown/route.ts @@ -1,10 +1,16 @@ import { NextResponse } from 'next/server' -import { readFileSync } from "fs"; +import { existsSync, readFileSync } from "fs"; import { join } from "path"; export async function GET() { const generatedPath = join(process.cwd(), 'generated', 'Introduction.md'); - let fileContent = undefined; + + if (!existsSync(generatedPath)) { + console.error(`File not found at path: ${generatedPath}`); + return NextResponse.json({ error: 'File not found' }, { status: 404 }); + } + + let fileContent: string; try { fileContent = readFileSync(generatedPath, 'utf-8'); } catch (error) { From 8a768e1dfc8aee0733766f58bb8443dc1cc701a3 Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 15:24:36 +0200 Subject: [PATCH 10/14] fix: login autocomplete webkit browser styling replaced with MUI colors --- Website/components/loginview/LoginView.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Website/components/loginview/LoginView.tsx b/Website/components/loginview/LoginView.tsx index 9694574..f52fed5 100644 --- a/Website/components/loginview/LoginView.tsx +++ b/Website/components/loginview/LoginView.tsx @@ -120,7 +120,14 @@ const LoginView = ({ }: LoginViewProps) => { )}
    - + Password Date: Sun, 28 Sep 2025 16:32:35 +0200 Subject: [PATCH 11/14] fix: dont only show custom M-M, but all if both entities are in the solution. --- Generator/DataverseService.cs | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/Generator/DataverseService.cs b/Generator/DataverseService.cs index 3bf58bd..7b95dd3 100644 --- a/Generator/DataverseService.cs +++ b/Generator/DataverseService.cs @@ -64,7 +64,6 @@ public DataverseService(IConfiguration configuration, ILogger var entityRootBehaviour = solutionComponents.Where(x => x.ComponentType == 1).ToDictionary(x => x.ObjectId, x => x.RootComponentBehavior); var attributesInSolution = solutionComponents.Where(x => x.ComponentType == 2).Select(x => x.ObjectId).ToHashSet(); var rolesInSolution = solutionComponents.Where(x => x.ComponentType == 20).Select(x => x.ObjectId).ToList(); - var pluginStepsInSolution = solutionComponents.Where(x => x.ComponentType == 92).Select(x => x.ObjectId).ToList(); var entitiesInSolutionMetadata = await GetEntityMetadata(entitiesInSolution); @@ -140,7 +139,7 @@ public DataverseService(IConfiguration configuration, ILogger .ToList(), RelevantManyToMany = x.ManyToManyRelationships - .Where(r => entityLogicalNamesInSolution.Contains(r.IntersectEntityName.ToLower())) + .Where(r => entityLogicalNamesInSolution.Contains(r.Entity1LogicalName) && entityLogicalNamesInSolution.Contains(r.Entity2LogicalName)) .ToList(), }) .Where(x => x.EntityMetadata.DisplayName.UserLocalizedLabel?.Label != null) @@ -215,16 +214,24 @@ private static Record MakeRecord( var manyToMany = relevantManyToMany .Where(x => logicalToSchema.ContainsKey(x.Entity1LogicalName) && logicalToSchema[x.Entity1LogicalName].IsInSolution) - .Select(x => new DTO.Relationship( - x.IsCustomRelationship ?? false, - x.Entity1AssociatedMenuConfiguration.Behavior == AssociatedMenuBehavior.UseLabel - ? x.Entity1AssociatedMenuConfiguration.Label.UserLocalizedLabel?.Label ?? x.Entity1NavigationPropertyName - : x.Entity1NavigationPropertyName, - logicalToSchema[x.Entity1LogicalName].Name, - "-", - x.SchemaName, - IsManyToMany: true, - null)) + .Select(x => + { + var useEntity1 = x.Entity1LogicalName == entity.LogicalName; + + var label = !useEntity1 + ? x.Entity1AssociatedMenuConfiguration.Label.UserLocalizedLabel?.Label ?? x.Entity1NavigationPropertyName + : x.Entity2AssociatedMenuConfiguration.Label.UserLocalizedLabel?.Label ?? x.Entity2NavigationPropertyName; + + return new DTO.Relationship( + x.IsCustomRelationship ?? false, + label, + logicalToSchema[!useEntity1 ? x.Entity1LogicalName : x.Entity2LogicalName].Name, + "-", + x.SchemaName, + IsManyToMany: true, + null + ); + }) .ToList(); Dictionary tablegroups = []; // logicalname -> group From 5c8ba70e36d33115e0a6ec11b1f0276ee6a3dc55 Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 16:38:56 +0200 Subject: [PATCH 12/14] feat: show spinner for when click relationship or lookup --- Website/components/datamodelview/Relationships.tsx | 3 ++- .../datamodelview/attributes/LookupAttribute.tsx | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Website/components/datamodelview/Relationships.tsx b/Website/components/datamodelview/Relationships.tsx index 458b29d..daa4c6b 100644 --- a/Website/components/datamodelview/Relationships.tsx +++ b/Website/components/datamodelview/Relationships.tsx @@ -368,7 +368,8 @@ export const Relationships = ({ entity, onVisibleCountChange, search = "" }: IRe color: 'primary.main' }} onClick={() => { - dispatch({ type: "SET_CURRENT_SECTION", payload: relationship.TableSchema }) + dispatch({ type: 'SET_LOADING_SECTION', payload: relationship.TableSchema }); + dispatch({ type: "SET_CURRENT_SECTION", payload: relationship.TableSchema }); scrollToSection(relationship.TableSchema); }} > diff --git a/Website/components/datamodelview/attributes/LookupAttribute.tsx b/Website/components/datamodelview/attributes/LookupAttribute.tsx index 3cc24bf..0534271 100644 --- a/Website/components/datamodelview/attributes/LookupAttribute.tsx +++ b/Website/components/datamodelview/attributes/LookupAttribute.tsx @@ -1,11 +1,12 @@ import { LookupAttributeType } from "@/lib/Types" -import { useDatamodelView } from "@/contexts/DatamodelViewContext" +import { useDatamodelView, useDatamodelViewDispatch } from "@/contexts/DatamodelViewContext" import { Box, Typography, Button, Chip } from "@mui/material" import { ContentPasteOffRounded, ContentPasteSearchRounded } from "@mui/icons-material"; export default function LookupAttribute({ attribute }: { attribute: LookupAttributeType }) { const { scrollToSection } = useDatamodelView(); + const dispatch = useDatamodelViewDispatch(); return ( @@ -18,7 +19,11 @@ export default function LookupAttribute({ attribute }: { attribute: LookupAttrib variant="outlined" size="small" startIcon={} - onClick={() => scrollToSection(target.Name)} + onClick={() => { + dispatch({ type: 'SET_LOADING_SECTION', payload: target.Name }); + dispatch({ type: "SET_CURRENT_SECTION", payload: target.Name }); + scrollToSection(target.Name); + }} sx={{ fontSize: { xs: '0.625rem', md: '0.875rem' }, height: { xs: '16px', md: '24px' }, From 3c67d99cff81907fb3f7feeed3bcbb930eb27183 Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 16:55:46 +0200 Subject: [PATCH 13/14] chore: removed old tab control code. It works if you have the section in view. --- Website/components/datamodelview/List.tsx | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Website/components/datamodelview/List.tsx b/Website/components/datamodelview/List.tsx index 90822e0..1cfb80c 100644 --- a/Website/components/datamodelview/List.tsx +++ b/Website/components/datamodelview/List.tsx @@ -30,10 +30,7 @@ export const List = ({ setCurrentIndex }: IListProps) => { const parentRef = useRef(null); // used to relocate section after search/filter const [sectionVirtualItem, setSectionVirtualItem] = useState(null); - - // Track position before search for restoration - const isTabSwitching = useRef(false); - + const handleCopyGroupLink = useCallback(async (groupName: string) => { const link = generateGroupLink(groupName); const success = await copyToClipboard(link); @@ -274,13 +271,7 @@ export const List = ({ setCurrentIndex }: IListProps) => { entity={item.entity} group={item.group} onTabChange={(isChanging: boolean) => { - isTabSwitching.current = isChanging; - if (isChanging) { - // Reset after a short delay to allow for the content change - setTimeout(() => { - isTabSwitching.current = false; - }, 100); - } + }} search={search} /> From 05bbc5d46232854dc61cde42470dcf6777776163 Mon Sep 17 00:00:00 2001 From: Lucki2g Date: Sun, 28 Sep 2025 17:11:13 +0200 Subject: [PATCH 14/14] chore: ESLint errors --- Website/app/api/markdown/route.ts | 2 +- Website/components/datamodelview/List.tsx | 2 +- Website/components/datamodelview/attributes/ChoiceAttribute.tsx | 2 +- Website/components/shared/Header.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Website/app/api/markdown/route.ts b/Website/app/api/markdown/route.ts index 59a3319..2b7cd4e 100644 --- a/Website/app/api/markdown/route.ts +++ b/Website/app/api/markdown/route.ts @@ -13,7 +13,7 @@ export async function GET() { let fileContent: string; try { fileContent = readFileSync(generatedPath, 'utf-8'); - } catch (error) { + } catch { return NextResponse.json({ error: 'File not found' }, { status: 404 }); } return NextResponse.json({ fileContent }) diff --git a/Website/components/datamodelview/List.tsx b/Website/components/datamodelview/List.tsx index 1cfb80c..21d3ebc 100644 --- a/Website/components/datamodelview/List.tsx +++ b/Website/components/datamodelview/List.tsx @@ -270,7 +270,7 @@ export const List = ({ setCurrentIndex }: IListProps) => {
    { + onTabChange={() => { }} search={search} diff --git a/Website/components/datamodelview/attributes/ChoiceAttribute.tsx b/Website/components/datamodelview/attributes/ChoiceAttribute.tsx index 972a8d8..4c8c47a 100644 --- a/Website/components/datamodelview/attributes/ChoiceAttribute.tsx +++ b/Website/components/datamodelview/attributes/ChoiceAttribute.tsx @@ -2,7 +2,7 @@ import { useIsMobile } from "@/hooks/use-mobile" import { ChoiceAttributeType } from "@/lib/Types" import { formatNumberSeperator } from "@/lib/utils" import { Box, Typography, Chip } from "@mui/material" -import { CheckBoxOutlineBlankRounded, CheckBoxRounded, CheckRounded, RadioButtonChecked, RadioButtonCheckedRounded, RadioButtonUncheckedRounded } from "@mui/icons-material" +import { CheckBoxOutlineBlankRounded, CheckBoxRounded, CheckRounded, RadioButtonCheckedRounded, RadioButtonUncheckedRounded } from "@mui/icons-material" export default function ChoiceAttribute({ attribute, highlightMatch, highlightTerm }: { attribute: ChoiceAttributeType, highlightMatch: (text: string, term: string) => string | React.JSX.Element, highlightTerm: string }) { diff --git a/Website/components/shared/Header.tsx b/Website/components/shared/Header.tsx index 9b11975..75c512e 100644 --- a/Website/components/shared/Header.tsx +++ b/Website/components/shared/Header.tsx @@ -2,7 +2,7 @@ import { useLoading } from '@/hooks/useLoading'; import { useAuth } from '@/contexts/AuthContext'; import { useSettings } from '@/contexts/SettingsContext'; import { useRouter } from 'next/navigation'; -import { AppBar, Toolbar, Box, LinearProgress, Button, Badge, Stack } from '@mui/material'; +import { AppBar, Toolbar, Box, LinearProgress, Button, Stack } from '@mui/material'; import SettingsPane from './elements/SettingsPane'; import { useIsMobile } from '@/hooks/use-mobile'; import { useSidebar } from '@/contexts/SidebarContext';