-
Notifications
You must be signed in to change notification settings - Fork 5
Add LMPG visualisation to dashboard UI #240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 80216f9 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
# Conflicts: # website/public/sitemap-0.xml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds LMPG (Large Multi-Property Graph) visualization capabilities to the dashboard UI, enabling users to view project data in both 2D and 3D graph formats. The changes refactor data fetching from async stores to react-query bridges for better performance and implement lazy loading of heavy graph components.
Key changes:
- Graph visualization implementation: New
useGraphDatahook and updatedGraphViewcomponent with 2D/3D modes and batch loading for up to 10k records - Data fetching refactor: Migrated project stores from async stores to react-query bridges for labels, records, relations, and fields
- Performance optimizations: Lazy loading of graph components, dynamic imports, and removal of unused invalidations
Reviewed Changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
platform/dashboard/src/lib/queryClient.ts |
Adds singleton QueryClient for non-hook based query usage |
platform/dashboard/src/features/projects/useGraphData.ts |
Implements graph data fetching with batch loading and store management |
platform/dashboard/src/features/projects/stores/current-project.ts |
Refactors stores to use react-query bridges while maintaining nanostore API |
platform/dashboard/src/features/projects/components/GraphView.tsx |
Complete rewrite supporting 2D/3D modes with dynamic imports and loading states |
platform/dashboard/src/features/projects/components/ProjectRecords.tsx |
Adds lazy loading for GraphView component |
platform/dashboard/src/features/records/stores/ |
Removes unused store invalidations for better performance |
platform/dashboard/package.json |
Updates dependencies to separate 2D/3D graph libraries |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| // @ts-ignore | ||
| $graphRecords.reset = () => { |
Copilot
AI
Aug 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace @ts-ignore with proper TypeScript typing. The method augmentation should be properly typed using module augmentation or interface merging.
| // @ts-ignore | |
| $graphRecords.reset = () => { | |
| ;($graphRecords as GraphStore<typeof $graphRecords.get()>).reset = () => { |
| // @ts-ignore | ||
| $graphRelations.reset = () => { |
Copilot
AI
Aug 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace @ts-ignore with proper TypeScript typing. The method augmentation should be properly typed using module augmentation or interface merging.
| // @ts-ignore | |
| $graphRelations.reset = () => { | |
| ($graphRelations as GraphRelationsStore).reset = () => { |
| }) | ||
| // @ts-ignore |
Copilot
AI
Aug 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace @ts-ignore with proper TypeScript typing. The method augmentation should be properly typed using module augmentation or interface merging.
| }) | |
| // @ts-ignore | |
| }) as CurrentProjectLabelsStore; |
| export const $filteredRecordsRelations = map<{ | ||
| data: any[] | undefined | ||
| loading: boolean | ||
| error?: string | ||
| total?: number | ||
| }>({ | ||
| data: undefined, | ||
| loading: true, | ||
| error: undefined, | ||
| total: undefined | ||
| }) | ||
| // @ts-ignore |
Copilot
AI
Aug 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace @ts-ignore with proper TypeScript typing. The method augmentation should be properly typed using module augmentation or interface merging.
| export const $filteredRecordsRelations = map<{ | |
| data: any[] | undefined | |
| loading: boolean | |
| error?: string | |
| total?: number | |
| }>({ | |
| data: undefined, | |
| loading: true, | |
| error: undefined, | |
| total: undefined | |
| }) | |
| // @ts-ignore | |
| interface FilteredRecordsRelationsValue { | |
| data: any[] | undefined | |
| loading: boolean | |
| error?: string | |
| total?: number | |
| } | |
| interface FilteredRecordsRelationsStore extends ReturnType<typeof map<FilteredRecordsRelationsValue>> { | |
| refetch: () => Promise<void> | |
| } | |
| export const $filteredRecordsRelations = map<FilteredRecordsRelationsValue>({ | |
| data: undefined, | |
| loading: true, | |
| error: undefined, | |
| total: undefined | |
| }) as FilteredRecordsRelationsStore |
| const GRAPH_BATCH_SIZE = 1000 | ||
| const GRAPH_MAX_RECORDS = 10000 | ||
| const GRAPH_MAX_BATCHES = GRAPH_MAX_RECORDS / GRAPH_BATCH_SIZE | ||
|
|
||
| // Graph-specific stores for fetching large datasets | ||
| type GraphRecordsQueryData = { data: unknown[]; total?: number; hasMore: boolean } | ||
|
|
||
| function buildGraphRecordsQueryArgs(skip = 0, limit = GRAPH_BATCH_SIZE) { |
Copilot
AI
Aug 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Consider making GRAPH_BATCH_SIZE configurable rather than a hard-coded constant, as optimal batch sizes may vary depending on network conditions and data complexity.
| const GRAPH_BATCH_SIZE = 1000 | |
| const GRAPH_MAX_RECORDS = 10000 | |
| const GRAPH_MAX_BATCHES = GRAPH_MAX_RECORDS / GRAPH_BATCH_SIZE | |
| // Graph-specific stores for fetching large datasets | |
| type GraphRecordsQueryData = { data: unknown[]; total?: number; hasMore: boolean } | |
| function buildGraphRecordsQueryArgs(skip = 0, limit = GRAPH_BATCH_SIZE) { | |
| export const DEFAULT_GRAPH_BATCH_SIZE = 1000 | |
| const GRAPH_MAX_RECORDS = 10000 | |
| const GRAPH_MAX_BATCHES = GRAPH_MAX_RECORDS / DEFAULT_GRAPH_BATCH_SIZE | |
| // Graph-specific stores for fetching large datasets | |
| type GraphRecordsQueryData = { data: unknown[]; total?: number; hasMore: boolean } | |
| function buildGraphRecordsQueryArgs(skip = 0, limit = DEFAULT_GRAPH_BATCH_SIZE) { |
| linkTarget="id" | ||
| linkSource="id" |
Copilot
AI
Aug 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The linkTarget and linkSource props should reference the link properties, not node properties. They should likely be "target" and "source" respectively to match the GraphLink type definition.
| linkTarget="id" | |
| linkSource="id" | |
| linkTarget="target" | |
| linkSource="source" |
platform/dashboard/src/features/projects/components/GraphView.tsx
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot <[email protected]>
shubhamos-ai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 Brilliant solution! The performance benchmarks are impressive, the memory usage is optimized, and the concurrent processing is handled expertly.
No description provided.