Skip to content

Commit d531e56

Browse files
aksOpsclaude
andcommitted
fix: unlimited file tree for codemap, edge kind stats, grayscale theme, nav colors
Codebase Map: - file-tree API now supports unlimited files (default Integer.MAX_VALUE) instead of capped at 10,000. Treemap shows complete codebase. - Added backward-compatible getFileTree(Integer) overload Edge breakdown: - Added edges_by_kind to StatsService.computeGraph() — counts edges by kind (calls, imports, contains, depends_on, etc.) - Dashboard Edges card now shows edge kind breakdown on click Theme: - Grayscale dark mode: #0a0a0a layout, #141414 container, #1a1a1a elevated - Menu colors explicit: gray text, blue selected, proper hover states - Layout/Header/Modal/Drawer backgrounds all set for both themes - Random colors on framework tags (magenta, cyan, gold, lime, etc.) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1db90da commit d531e56

6 files changed

Lines changed: 59 additions & 10 deletions

File tree

src/main/frontend/src/main.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,34 @@ function ThemedApp() {
4242
}),
4343
},
4444
components: {
45+
Layout: {
46+
headerBg: isDark ? '#141414' : '#ffffff',
47+
bodyBg: isDark ? '#0a0a0a' : '#f7f7f8',
48+
siderBg: isDark ? '#141414' : '#ffffff',
49+
},
4550
Table: {
46-
headerBg: isDark ? '#1c1c1c' : '#fafafa',
51+
headerBg: isDark ? '#1a1a1a' : '#fafafa',
4752
rowHoverBg: isDark ? '#1f1f1f' : '#f5f5ff',
4853
},
4954
Card: {
5055
paddingLG: 20,
56+
colorBgContainer: isDark ? '#141414' : '#ffffff',
5157
},
5258
Menu: {
5359
itemBg: 'transparent',
5460
darkItemBg: 'transparent',
61+
horizontalItemSelectedBg: isDark ? '#1a1a1a' : '#e6f4ff',
62+
horizontalItemSelectedColor: isDark ? '#60a5fa' : '#2563eb',
63+
itemColor: isDark ? '#a0a0a0' : '#595959',
64+
itemHoverColor: isDark ? '#e0e0e0' : '#1d1d1d',
65+
itemSelectedColor: isDark ? '#60a5fa' : '#2563eb',
66+
},
67+
Modal: {
68+
contentBg: isDark ? '#1a1a1a' : '#ffffff',
69+
headerBg: isDark ? '#1a1a1a' : '#ffffff',
70+
},
71+
Drawer: {
72+
colorBgElevated: isDark ? '#1a1a1a' : '#ffffff',
5573
},
5674
},
5775
}}>

src/main/frontend/src/pages/Dashboard.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@ import { useApi } from '@/hooks/useApi';
1414
import { api } from '@/lib/api';
1515
import type { StatsResponse } from '@/types/api';
1616

17+
const TAG_COLORS = [
18+
'magenta', 'red', 'volcano', 'orange', 'gold',
19+
'lime', 'green', 'cyan', 'blue', 'geekblue', 'purple',
20+
];
21+
22+
function hashCode(str: string): number {
23+
let hash = 0;
24+
for (let i = 0; i < str.length; i++) {
25+
hash = ((hash << 5) - hash) + str.charCodeAt(i);
26+
hash |= 0;
27+
}
28+
return hash;
29+
}
30+
1731
/** Flatten a value into a Record<string, number>. Handles nested objects, numbers, arrays. */
1832
function flattenToRecord(val: unknown): Record<string, number> {
1933
if (!val || typeof val !== 'object') return {};
@@ -247,7 +261,7 @@ export default function Dashboard() {
247261
{Object.entries(frameworks)
248262
.sort((a, b) => b[1] - a[1])
249263
.map(([name, count]) => (
250-
<Tag key={name} color="blue">{name} ({count})</Tag>
264+
<Tag key={name} color={TAG_COLORS[Math.abs(hashCode(name)) % TAG_COLORS.length]}>{name} ({count})</Tag>
251265
))}
252266
</div>
253267
</Card>

src/main/java/io/github/randomcodespace/iq/api/GraphController.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,13 @@ public List<Map<String, Object>> searchGraph(
204204

205205
@GetMapping("/file-tree")
206206
public Map<String, Object> getFileTree(
207-
@RequestParam(required = false) Integer depth) {
207+
@RequestParam(required = false) Integer depth,
208+
@RequestParam(required = false) Integer maxFiles) {
208209
requireQueryService();
209210
int cappedDepth = (depth != null) ? Math.min(depth, config.getMaxDepth()) : config.getMaxDepth();
210-
return queryService.getFileTree(cappedDepth);
211+
// Default unlimited for treemap; pass maxFiles to limit if needed
212+
int limit = (maxFiles != null) ? maxFiles : Integer.MAX_VALUE;
213+
return queryService.getFileTree(cappedDepth, limit);
211214
}
212215

213216
@GetMapping("/capabilities")

src/main/java/io/github/randomcodespace/iq/query/QueryService.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,13 @@ public List<Map<String, Object>> searchGraph(String query, int limit) {
354354
*
355355
* @param maxDepth limit tree depth; null means unlimited
356356
*/
357-
@Cacheable(value = "file-tree", key = "#maxDepth")
358357
public Map<String, Object> getFileTree(Integer maxDepth) {
359-
GraphStore.FilePathResult filePathResult = graphStore.getFilePathsWithCounts(config.getMaxFiles());
358+
return getFileTree(maxDepth, config.getMaxFiles());
359+
}
360+
361+
@Cacheable(value = "file-tree", key = "#maxDepth + '-' + #maxFiles")
362+
public Map<String, Object> getFileTree(Integer maxDepth, int maxFiles) {
363+
GraphStore.FilePathResult filePathResult = graphStore.getFilePathsWithCounts(maxFiles);
360364
List<Map<String, Object>> rows = filePathResult.rows();
361365

362366
TreeNode root = new TreeNode("", PROP_DIRECTORY);

src/main/java/io/github/randomcodespace/iq/query/StatsService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,18 @@ Map<String, Object> computeGraph(List<CodeNode> nodes, List<CodeEdge> edges) {
6969
.distinct()
7070
.count();
7171

72+
// Edge kind breakdown
73+
Map<String, Long> edgesByKind = new TreeMap<>();
74+
for (CodeEdge edge : edges) {
75+
String kind = edge.getKind() != null ? edge.getKind().getValue() : "unknown";
76+
edgesByKind.merge(kind, 1L, Long::sum);
77+
}
78+
7279
Map<String, Object> graph = new LinkedHashMap<>();
7380
graph.put("nodes", nodes.size());
7481
graph.put("edges", edges.size());
7582
graph.put("files", fileCount);
83+
graph.put("edges_by_kind", new LinkedHashMap<>(sortByValueDesc(edgesByKind)));
7684
return graph;
7785
}
7886

src/test/java/io/github/randomcodespace/iq/api/GraphControllerTest.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
import static org.hamcrest.Matchers.*;
2424
import static org.mockito.ArgumentMatchers.any;
25+
import static org.mockito.ArgumentMatchers.anyInt;
26+
import static org.mockito.ArgumentMatchers.eq;
2527
import static org.mockito.Mockito.verify;
2628
import static org.mockito.Mockito.when;
2729
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -565,7 +567,7 @@ void getFileTreeShouldReturnHierarchicalTree() throws Exception {
565567
Map.of("name", "src", "type", "directory", "nodeCount", 10L, "children", List.of()),
566568
Map.of("name", "pom.xml", "type", "file", "nodeCount", 1L, "children", List.of())));
567569
treeResult.put("total_files", 3L);
568-
when(queryService.getFileTree(10)).thenReturn(treeResult);
570+
when(queryService.getFileTree(anyInt(), anyInt())).thenReturn(treeResult);
569571

570572
mockMvc.perform(get("/api/file-tree"))
571573
.andExpect(status().isOk())
@@ -583,7 +585,7 @@ void getFileTreeShouldPassDepthParam() throws Exception {
583585
Map<String, Object> treeResult = new LinkedHashMap<>();
584586
treeResult.put("tree", List.of());
585587
treeResult.put("total_files", 0L);
586-
when(queryService.getFileTree(2)).thenReturn(treeResult);
588+
when(queryService.getFileTree(eq(2), anyInt())).thenReturn(treeResult);
587589

588590
mockMvc.perform(get("/api/file-tree").param("depth", "2"))
589591
.andExpect(status().isOk())
@@ -595,12 +597,12 @@ void getFileTreeShouldCapDepthAtMaxDepth() throws Exception {
595597
Map<String, Object> treeResult = new LinkedHashMap<>();
596598
treeResult.put("tree", List.of());
597599
treeResult.put("total_files", 0L);
598-
when(queryService.getFileTree(10)).thenReturn(treeResult);
600+
when(queryService.getFileTree(eq(10), anyInt())).thenReturn(treeResult);
599601

600602
mockMvc.perform(get("/api/file-tree").param("depth", "999"))
601603
.andExpect(status().isOk())
602604
.andExpect(jsonPath("$.total_files").value(0));
603605

604-
verify(queryService).getFileTree(10);
606+
verify(queryService).getFileTree(eq(10), anyInt());
605607
}
606608
}

0 commit comments

Comments
 (0)