Skip to content

Commit 6f440c8

Browse files
authored
Add SchemaGraph module and UI improvements (#1492)
* Enable code intelligence, update steeing * Remove disable logic for zoom in & out * Don’t hide whole screen when schema sync fetching * Update small button style * Update Chip styling to add subtle variants * Move SelectLayout to components/Graph * feat: Add SchemaGraph module with graph transformation utilities - Create useSchemaGraphNodes hook to transform vertex types to graph nodes - Create useSchemaGraphEdges hook to transform edge connections to graph edges - Create SchemaGraph component with zoom/layout controls - Integrate SchemaGraph into SchemaExplorer route - Reuse existing graph styles for consistent visualization Tasks 8-9 of schema-explorer spec * Simplify use of edge connection id * Add EdgeConnectionId to branded types in steering * Move schemaExplorerLayout * Undo export of Arrow * Cleanup imports and constants * Remove pointless use of cn() * Update some UI labels and spacing * Allow properties to wrap if name or type is too long * Ensure property counts are formatted * Remove unused code * Remove sidebar onClose * Fix formatting * Add better typeing in graph data
1 parent f3a07c9 commit 6f440c8

34 files changed

+1323
-135
lines changed

.kiro/settings/lsp.json

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
{
2+
"languages": {
3+
"rust": {
4+
"name": "rust-analyzer",
5+
"command": "rust-analyzer",
6+
"args": [],
7+
"file_extensions": ["rs"],
8+
"project_patterns": ["Cargo.toml"],
9+
"exclude_patterns": ["**/target/**"],
10+
"multi_workspace": false,
11+
"initialization_options": {
12+
"cargo": {
13+
"buildScripts": {
14+
"enable": true
15+
}
16+
},
17+
"diagnostics": {
18+
"enable": true,
19+
"enableExperimental": true
20+
},
21+
"workspace": {
22+
"symbol": {
23+
"search": {
24+
"scope": "workspace"
25+
}
26+
}
27+
}
28+
},
29+
"request_timeout_secs": 60
30+
},
31+
"python": {
32+
"name": "pyright",
33+
"command": "pyright-langserver",
34+
"args": ["--stdio"],
35+
"file_extensions": ["py"],
36+
"project_patterns": [
37+
"pyproject.toml",
38+
"setup.py",
39+
"requirements.txt",
40+
"pyrightconfig.json"
41+
],
42+
"exclude_patterns": [
43+
"**/__pycache__/**",
44+
"**/venv/**",
45+
"**/.venv/**",
46+
"**/.pytest_cache/**"
47+
],
48+
"multi_workspace": false,
49+
"initialization_options": {},
50+
"request_timeout_secs": 60
51+
},
52+
"ruby": {
53+
"name": "solargraph",
54+
"command": "solargraph",
55+
"args": ["stdio"],
56+
"file_extensions": ["rb"],
57+
"project_patterns": ["Gemfile", "Rakefile"],
58+
"exclude_patterns": ["**/vendor/**", "**/tmp/**"],
59+
"multi_workspace": false,
60+
"initialization_options": {},
61+
"request_timeout_secs": 60
62+
},
63+
"typescript": {
64+
"name": "typescript-language-server",
65+
"command": "typescript-language-server",
66+
"args": ["--stdio"],
67+
"file_extensions": ["ts", "js", "tsx", "jsx"],
68+
"project_patterns": ["package.json", "tsconfig.json"],
69+
"exclude_patterns": ["**/node_modules/**", "**/dist/**"],
70+
"multi_workspace": false,
71+
"initialization_options": {
72+
"preferences": {
73+
"disableSuggestions": false
74+
}
75+
},
76+
"request_timeout_secs": 60
77+
},
78+
"go": {
79+
"name": "gopls",
80+
"command": "gopls",
81+
"args": [],
82+
"file_extensions": ["go"],
83+
"project_patterns": ["go.mod", "go.sum"],
84+
"exclude_patterns": ["**/vendor/**"],
85+
"multi_workspace": false,
86+
"initialization_options": {
87+
"usePlaceholders": true,
88+
"completeUnimported": true
89+
},
90+
"request_timeout_secs": 60
91+
},
92+
"java": {
93+
"name": "jdtls",
94+
"command": "jdtls",
95+
"args": [],
96+
"file_extensions": ["java"],
97+
"project_patterns": [
98+
"pom.xml",
99+
"build.gradle",
100+
"build.gradle.kts",
101+
".project"
102+
],
103+
"exclude_patterns": ["**/target/**", "**/build/**", "**/.gradle/**"],
104+
"multi_workspace": false,
105+
"initialization_options": {
106+
"settings": {
107+
"java": {
108+
"compile": {
109+
"nullAnalysis": {
110+
"mode": "automatic"
111+
}
112+
},
113+
"configuration": {
114+
"annotationProcessing": {
115+
"enabled": true
116+
}
117+
}
118+
}
119+
}
120+
},
121+
"request_timeout_secs": 60
122+
},
123+
"cpp": {
124+
"name": "clangd",
125+
"command": "clangd",
126+
"args": ["--background-index"],
127+
"file_extensions": ["cpp", "cc", "cxx", "c", "h", "hpp", "hxx"],
128+
"project_patterns": [
129+
"CMakeLists.txt",
130+
"compile_commands.json",
131+
"Makefile"
132+
],
133+
"exclude_patterns": ["**/build/**", "**/cmake-build-**/**"],
134+
"multi_workspace": false,
135+
"initialization_options": {},
136+
"request_timeout_secs": 60
137+
}
138+
}
139+
}

.kiro/steering/product.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ database types and query languages.
2929
- **Tabular View**: Show/hide nodes and edges, export to CSV/JSON
3030
- **Data Explorer**: List all nodes and properties for a specific node type and
3131
send to graph view
32+
- **Schema Explorer**: View node types and their relationships as a graph
3233
- **Authentication**: AWS IAM authentication via SigV4 signing protocol
3334

3435
## Architecture

.kiro/steering/structure.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,29 @@ inclusion: always
7171
- Layout preferences
7272
- **External Data**: Graph data is queried directly from the connected graph
7373
databases and is not owned or persisted by Graph Explorer
74+
75+
## Branded Types
76+
77+
The project uses branded types from `@/utils` for type safety. These prevent
78+
accidental mixing of similar types at compile time.
79+
80+
| Type | Creator Function | Location |
81+
| ------------------ | ---------------------------- | --------------------------------------- |
82+
| `VertexId` | `createVertexId()` | `@/core/entities/vertex` |
83+
| `VertexType` | `createVertexType()` | `@/core/entities/vertex` |
84+
| `EdgeId` | `createEdgeId()` | `@/core/entities/edge` |
85+
| `EdgeType` | `createEdgeType()` | `@/core/entities/edge` |
86+
| `EdgeConnectionId` | `createEdgeConnectionId()` | `@/core/StateProvider/edgeConnectionId` |
87+
| `ConfigurationId` | `createNewConfigurationId()` | `@/core/ConfigurationProvider/types` |
88+
| `RenderedVertexId` | `toRenderedVertexId()` | `@/core/StateProvider/renderedEntities` |
89+
| `RenderedEdgeId` | `toRenderedEdgeId()` | `@/core/StateProvider/renderedEntities` |
90+
91+
Always use the appropriate branded type instead of `string` when working with
92+
these identifiers.
93+
94+
## Database Queries
95+
96+
- Use the `query` template tag from `@/utils` for all query strings (Gremlin,
97+
openCypher, SPARQL) to ensure consistent formatting
98+
- For Gremlin queries, use `escapeString()` from `@/utils` to escape special
99+
characters in string literals

AGENTS.md

Lines changed: 26 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
declarations (e.g., `function handleClick() {}` over
1111
`const handleClick = () => {}`). Arrow functions within function scope are
1212
fine.
13-
- Imports are sorted using ESLint, which can be invoked for a single file using
14-
`pnpm eslint --fix <path-to-file>`
13+
- Every commit should have no type errors, lint errors, or failing tests
14+
- When possible, create failing tests first then implement the logic to make the
15+
tests pass
16+
- Add or update tests for the code you change, even if nobody asked
1517

1618
### React Rules
1719

@@ -20,9 +22,16 @@
2022
- Avoid prop drilling - use context or state management
2123
- Follow principle of least privilege for component props
2224

25+
### Tailwind Rules
26+
27+
- Use Tailwind v4 CSS syntax
28+
- The `tailwind.config.ts` file remains for legacy reasons
29+
2330
## Project Commands
2431

32+
- This project uses `pnpm` only, never use `npm`
2533
- All commands should be run from the root of the project repository
34+
- Assume dev server is always running
2635

2736
### Development
2837

@@ -32,32 +41,28 @@
3241

3342
### Quality Checks
3443

35-
- `pnpm lint` - Fix linting issues
36-
- `pnpm check:lint` - Check linting only
37-
- `pnpm format` - Format code
38-
- `pnpm check:format` - Check formatting only
39-
- `pnpm check:types` - Type checking
40-
- `pnpm checks` - Run all checks
44+
- `pnpm checks` - Run checks for linting, types, and formatting in parallel
45+
- `pnpm check:types` - Check for TypeScript type errors
46+
- `pnpm check:lint` - Check for lint errors
47+
- `pnpm check:format` - Check for formatting errors
48+
- `pnpm lint` - Fix any fixable linting errors
49+
- `pnpm lint <path-to-file>` - Fix any fixable linting errors for a specific
50+
file
51+
- `pnpm format` - Format all files
4152

4253
### Testing
4354

44-
- `pnpm test` - Run tests
45-
- `pnpm test:watch` - Watch mode
46-
- `pnpm coverage` - Test coverage
47-
- `pnpm vitest --run <path-to-file>` - Run tests for specific file
48-
49-
### Maintenance
50-
51-
- `pnpm clean` - Clean build artifacts
52-
- `pnpm clean:dep` - Remove node_modules
55+
- `pnpm test` - Run all tests
56+
- `pnpm test <path-to-file>` - Run tests for specific file
57+
- `pnpm coverage` - Check test coverage
5358

5459
### Git
5560

5661
- `git --no-pager` - Disable pager for git commands
5762

5863
### Dependency Management
5964

60-
Add dependency to specific package
65+
Add dependency to specific workspace
6166

6267
```bash
6368
pnpm add <package> --filter <workspace-name>
@@ -118,15 +123,15 @@ src/
118123
### Frontend (graph-explorer)
119124

120125
- React 19 + TypeScript
126+
- React Compiler (no manual useMemo/useCallback needed)
121127
- Vite build tool
122128
- TailwindCSS + Radix UI components
123129
- React Router for routing
124130
- Cytoscape.js for graph visualization
125-
- React Query for data fetching
131+
- TanStack Query (formerly called React Query) for data fetching
126132
- Jotai for state management
127-
- React Hook Form + Zod validation
128133
- LocalForage for persistent app state
129-
- React Compiler (no manual useMemo/useCallback needed)
134+
- React Hook Form + Zod validation
130135

131136
### Backend (proxy-server)
132137

@@ -155,39 +160,4 @@ src/
155160

156161
### Testing
157162

158-
- From the package root you can just call `pnpm test`. The commit should pass
159-
all tests before you merge.
160-
- To focus on one step, add the Vitest pattern:
161-
`pnpm vitest run -t "<test name>"`.
162-
- Fix any test or type errors until the whole suite is green.
163-
- After moving files or changing imports, run
164-
`pnpm lint --filter <project_name>` to be sure ESLint and TypeScript rules
165-
still pass.
166-
- Add or update tests for the code you change, even if nobody asked.
167-
168163
See `.kiro/steering/testing.md` for testing patterns and examples.
169-
170-
### Branded Types
171-
172-
The project uses branded types from `@/utils` for type safety. These prevent
173-
accidental mixing of similar types at compile time.
174-
175-
| Type | Creator Function | Location |
176-
| ------------------ | ---------------------------- | --------------------------------------- |
177-
| `VertexId` | `createVertexId()` | `@/core/entities/vertex` |
178-
| `VertexType` | `createVertexType()` | `@/core/entities/vertex` |
179-
| `EdgeId` | `createEdgeId()` | `@/core/entities/edge` |
180-
| `EdgeType` | `createEdgeType()` | `@/core/entities/edge` |
181-
| `ConfigurationId` | `createNewConfigurationId()` | `@/core/ConfigurationProvider/types` |
182-
| `RenderedVertexId` | `toRenderedVertexId()` | `@/core/StateProvider/renderedEntities` |
183-
| `RenderedEdgeId` | `toRenderedEdgeId()` | `@/core/StateProvider/renderedEntities` |
184-
185-
Always use the appropriate branded type instead of `string` when working with
186-
these identifiers.
187-
188-
### Database Queries
189-
190-
- Use the `query` template tag from `@/utils` for all query strings (Gremlin,
191-
openCypher, SPARQL) to ensure consistent formatting
192-
- For Gremlin queries, use `escapeString()` from `@/utils` to escape special
193-
characters in string literals

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"scripts": {
1414
"prepare": "husky install",
1515
"precommit": "lint-staged && pnpm check:types",
16-
"lint": "eslint . --fix --concurrency=auto",
17-
"check:lint": "eslint . --concurrency=auto",
16+
"lint": "eslint --fix --concurrency=auto",
17+
"check:lint": "eslint --concurrency=auto",
1818
"format": "prettier --write .",
1919
"check:format": "prettier --check .",
2020
"test": "vitest run",

packages/graph-explorer/src/components/Button/Button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const buttonStyles = cva({
1919
danger: "",
2020
},
2121
size: {
22-
small: "h-8 rounded-sm px-2 text-base [&_svg]:size-5",
22+
small: "h-8 rounded-md px-2 text-sm [&_svg]:size-4",
2323
base: "h-10 rounded-md px-4 text-base [&_svg]:size-5",
2424
large: "h-12 rounded-md px-5 text-lg [&_svg]:size-6",
2525
},

packages/graph-explorer/src/components/Chip.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ import { cva, type VariantProps } from "cva";
55
import { cn } from "@/utils";
66

77
const chip = cva({
8-
base: "chip inline-flex h-[22px] items-center justify-center gap-1 overflow-hidden rounded-full px-2.5 text-sm font-medium text-ellipsis whitespace-nowrap text-white select-none [&>svg]:size-4",
8+
base: "chip inline-flex h-[22px] items-center justify-center gap-1 overflow-hidden rounded-full px-2.5 text-sm leading-none font-medium text-ellipsis whitespace-nowrap text-white select-none [&>svg]:size-4",
99
variants: {
1010
variant: {
11+
neutral: "bg-neutral",
12+
"neutral-subtle":
13+
"bg-neutral-subtle text-neutral-foreground border-neutral-foreground/25 border",
1114
primary: "bg-primary-main",
15+
"primary-subtle":
16+
"bg-primary-subtle text-primary-foreground border-primary-foreground/25 border",
1217
success: "bg-success-main",
1318
error: "bg-error-main",
1419
warning: "bg-warning-main",

packages/graph-explorer/src/components/Graph/GraphControlButtons.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,27 @@ export function ZoomToFitButton() {
3939
}
4040

4141
export function ZoomInButton() {
42-
const { onZoomIn, isZoomInDisabled } = useGraphGlobalActions();
42+
const { onZoomIn } = useGraphGlobalActions();
4343

4444
return (
4545
<IconButton
4646
tooltipText="Zoom in"
4747
icon={<ZoomInIcon />}
4848
variant="text"
4949
onClick={onZoomIn}
50-
disabled={isZoomInDisabled}
5150
/>
5251
);
5352
}
5453

5554
export function ZoomOutButton() {
56-
const { onZoomOut, isZoomOutDisabled } = useGraphGlobalActions();
55+
const { onZoomOut } = useGraphGlobalActions();
5756

5857
return (
5958
<IconButton
6059
tooltipText="Zoom out"
6160
icon={<ZoomOutIcon />}
6261
variant="text"
6362
onClick={onZoomOut}
64-
disabled={isZoomOutDisabled}
6563
/>
6664
);
6765
}

0 commit comments

Comments
 (0)